(流利)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,因此手动设置引用不是解决方案
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()
......