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();
}
}