NHibernate双向关联

时间:2012-03-28 17:03:07

标签: nhibernate fluent-nhibernate

我正在尝试建模一个父/子关联,其中父类(Person)拥有子类的许多实例(OwnedThing) - 我希望在保存Person类时自动保存OwnedThing实例,我想要这种关联是双向的。

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设置为Inverse,则在保存Person时不会保存OwnedThing实例。如果我不添加Inverse,那么保存成功但是person.OwnedThings [0] .Owner在从数据库中检索后总是为空。

更新 保存数据时,NHibernate会在数据库中设置单个关联结束,因为它是通过关联的多端设置的,所以当我从数据库中检索OwnedThing时,确实将链接返回到人物集。我的空引用来自Envers,它似乎没有做同样的事情。

2 个答案:

答案 0 :(得分:0)

OwnedThings[0].Owner很可能为null,因为您在执行添加时未设置它。使用双向关系时,您必须执行以下操作:

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

答案 1 :(得分:0)

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

如果是这样,可能是由此错误造成的 https://nhibernate.jira.com/browse/NHE-64 现在的解决方法是使用Merge而不是(SaveOr)Update。