NHibernate双向关联

问题描述:

我想模拟一个父类/子关联,其中一个父类(Person)拥有一个子类(OwnedThing)的许多实例 - 我想在Person类是自动保存的OwnedThing实例保存下来,我希望该协会是双向的。NHibernate双向关联

public class Person 
{ 
     public class MAP_Person : ClassMap<Person> 
     { 
       public MAP_Person() 
       { 
         this.Table("People"); 
         this.Id(x => x.ID).GeneratedBy.GuidComb().Access.BackingField(); 
         this.Map(x => x.FirstName); 
         this.HasMany(x => x.OwnedThings).Cascade.AllDeleteOrphan().KeyColumn("OwnerID").Inverse(); 
       } 
     } 

     public virtual Guid ID { get; private set; } 
     public virtual string FirstName { get; set; } 
     public virtual IList<OwnedThing> OwnedThings { get; set; } 

     public Person() 
     { 
       OwnedThings = new List<OwnedThing>(); 
     } 
} 



public class OwnedThing 
{ 
     public class MAP_OwnedThing : ClassMap<OwnedThing> 
     { 
       public MAP_OwnedThing() 
       { 
         this.Table("OwnedThings"); 
         this.Id(x => x.ID).GeneratedBy.GuidComb().Access.BackingField(); 
         this.Map(x => x.Name); 
         this.References(x => x.Owner).Column("OwnerID").Access.BackingField(); 
       } 
     } 

     public virtual Guid ID { get; private set; } 
     public virtual Person Owner { get; private set; } 
     public virtual string Name { get; set; } 
} 

如果我设置Person.OwnedThings反演那么OwnedThing情况下不会被保存,当我救的人。如果我不添加逆,那么保存成功,但是person.OwnedThings [0] .Owner在从数据库中检索到后始终为空。

UPDATE 在保存数据的NHibernate将设置一个关联端的数据库,因为它是通过该协会的许多高端设置,所以当我从它确实数据库检索OwnedThing有链接回人员组。我的空引用来自Envers,似乎并没有做同样的事情。

我是否正确理解你的问题只发生在由nhibernate envers读取的“历史”实体上?

如果是的话,它可能会受到此问题的 https://nhibernate.jira.com/browse/NHE-64 解决办法,现在是使用合并,而不是(SaveOr)更新造成的。

OwnedThings[0].Owner很可能为空,因为您在添加时未设置它。当使用双向关系中,你必须做类似下面:

Person person = new Person(); 
OwnedThing pwnedThing = new OwnedThing(); 

pwnedThing.Owner = person; 
person.OwnedThings.Add(pwnedThing); 

如果不明确地设置pwnedThing.Owner和您查询的是,在同一个ISession同一个对象,你创建它就会为空。通常我会添加或删除为我做这个“额外”工作的方法。以下例子:

public class Order : Entity 
{ 
    private IList<OrderLine> orderLines; 
    public virtual IEnumerable<OrderLine> OrderLines { get { return orderLines.Select(x => x); } } 

    public virtual void AddLine(OrderLine orderLine) 
    { 
     orderLine.Order = this; 
     this.orderLines.Add(orderLine); 
    } 

    public virtual void RemoveLine(OrderLine orderLine) 
    { 
     this.orderLines.Remove(orderLine); 
    } 
} 

public class OrderMap : ClassMap<Order> 
{ 
    public OrderMap() 
    { 
     DynamicUpdate(); 
     Table("ORDER_HEADER"); 
     Id(x => x.Id, "ORDER_ID"); 

     HasMany(x => x.OrderLines) 
      .Access.CamelCaseField() 
      .KeyColumn("ORDER_ID") 
      .Inverse() 
      .Cascade.AllDeleteOrphan(); 
    } 
}