NHibernate - 无法保存子实体

时间:2015-02-17 08:42:49

标签: nhibernate fluent-nhibernate-mapping

这应该是一个简单的1-N关系,但是我无法保存子节点,因为NHibernate在子元素的insert语句中使用null作为值。

 public class Event
 {
  public virtual string Id { get; set; }
  public virtual string Name { get; set; }        
  public virtual IList<EventParameter> Parameters{ get; set; }

  public Event() { Parameters = new List<EventParameter>(); }
 }

[Serializable]
public class EventParameter : Parameter
{
  public virtual Event Event { get; set; }
  public virtual string ComparisonMethod { get; set; }
  public override bool Equals(object obj) {}
  public override int GetHashCode() {}
}

映射就像这样

public EventMapping()
{
    Table(...);

    Id(x => x.Id)
        .Column(...)
        .GeneratedBy
        .Custom<global::NHibernate.Id.SequenceGenerator>(builder => builder.AddParam("sequence", "...")); 

    Map(x => x.Name).Column("Name").Length(100);

    HasMany<EventParameter>(x => x.Parameters)
            .KeyColumns.Add(...)
            .Inverse()
            .Cascade.All();
}

public EventParameterMapping()
{
    Table(....);

    CompositeId()
        .KeyProperty(x => x.Event.Id, "...")
        .KeyProperty(x => x.ParameterId, "..."); 

    References(x => x.Event);          
}

父项的Insert语句是正确的,但对于子项而言则不是。

INSERT INTO ...
        (...columns...)
VALUES  (..., null, ...)

在此之前我收到以下警告:无法确定实体是暂时的还是分离的;查询数据库。在会话中使用显式Save()或Update()来防止这种情况。

我在事务中使用Save()。任何想法为什么会这样?

1 个答案:

答案 0 :(得分:1)

这里的解决方案简直令人惊讶。我们必须使用 inverse="true" 映射:

HasMany<EventParameter>(x => x.Children)
        .KeyColumns.Add("...")
        .Inverse()
        .Cascade.All();

但是,这是一种优化,这需要在我们的C#代码中始终正确设置关系的双方:

var parent = ...;
var child = new Child();
// both sides MUST be set
parent.Children.Add(child);
child.Parent = parent;

请详细了解

Inverse = “true” example and explanation