(流利)NHibernate:HasMany/References(双向)+级联保存

本文关键字:双向 级联 保存 References HasMany 流利 NHibernate | 更新日期: 2024-10-30 19:08:34

如何在 X 引用 Y 的情况下配置

双向映射的映射,Y 有很多 X,以便当我向 Y 实例添加许多 X 并保存 Y 实例时,它会正常工作?

为了明确问题,以下是代码:

客户公司模型具有HasMany联系人相关模型:

public class ClientCompany
{
    // .... 
    public virtual ISet<ContactPerson> ContactPeople { get; set; }
}
// mapping:
HasMany(x => x.ContactPeople)
            .AsSet()
            .Inverse()
            .Cascade.All();

联系人具有引用母公司的不可为空的"客户公司"字段:

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

导致此异常:

非空属性引用空值或瞬态值 xxxx.联系人.客户公司

这只是简化的情况,我在实际项目中使用 AutoMapper,因此手动设置引用不是解决方案

(流利)NHibernate:HasMany/References(双向)+级联保存

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()......