(流畅)NHibernate:HasMany / References(双向)+ Cascade Save

时间:2015-03-08 18:28:46

标签: c# nhibernate fluent-nhibernate

如何在 X引用Y,Y有很多X 的场景中配置双向映射的映射,这样当我向Y实例添加多个X并保存Y实例时,它就会#39 ;工作正常吗?

要明确问题,请输入以下代码:

ClientCompany 模型有HasMany ContactPerson 相关模型:

public class ClientCompany
{
    // .... 
    public virtual ISet<ContactPerson> ContactPeople { get; set; }
}

// mapping:
HasMany(x => x.ContactPeople)
            .AsSet()
            .Inverse()
            .Cascade.All();

ContactPerson 无法访问&#34; ClientCompany&#34;引用母公司的字段:

public class ContactPerson
{
    // ....
    public virtual ClientCompany ClientCompany { get; set; }
}

References(x => x.ClientCompany).Not.Nullable();

调用此代码:

sess.Save(new ClientCompany()
            {                    
                ContactPeople = new HashSet<ContactPerson>()
                {
                    new ContactPerson()
                }
            });

导致此异常:

  

not-null属性引用null或transient值   xxxx.ContactPerson.ClientCompany

这只是简化案例,我在实际项目中使用AutoMapper,因此手动设置参考 不是解决方案

1 个答案:

答案 0 :(得分:3)

ORM世界中最重要的想法,即使用NHibernate时,是:

  

始终设置关系的 两侧。

这是有效的方法,如何设置双方:

var person = new ContactPerson();
var company = new ClientCompany
{                    
    ContactPeople = new HashSet<ContactPerson>()
    {
        person,
    },
};
person.ClientCompany = company

sess.Save(company);

通过映射,Person被声明为负责其关系(逆映射 .Inverse() )。

这意味着它必须将关系设置为其父级。此关系稍后用于INSERT语句...并且它不能为空。

没有必要单独保存公司和个人。 唯一必要绝对重要的事情是设置两个参考边。那是必须的。

不确定使用自动映射器可以做什么...但是对于POCO对象,某些包装/屏蔽双向设置可能是一些特殊的方法:

public class ClientCompany
{
    // .... 
    public virtual ISet<ContactPerson> ContactPeople { get; set; }
    public virtual AddPerson(ContactPerson person)
    {
        ContactPeople = ContactPeople ?? new HashSet<ContactPerson>();
        ContactPeople.Add(person);
        person.ClientCompany = this;
    }
}

现在我们只需要在合适的时间致电AddPerson() ......