我有一个域结构,其中包含一个Policy对象(一个人寿保险单),该对象上有一个Owners and Lives(生命被保险)的集合。它们与我们称之为OwnerLifeRelationship的连接表相关联。这些关系仅在Owner类上公开,而不在Life类上公开。对两个连接表强制执行外键约束,对所有者上的Relationships包的NHibernate映射强制执行:
<bag name="Relationships"
inverse="true"
lazy="true"
cascade="all-delete-orphan"
access="field.camelcase-underscore" >
<key>
<column name="OwnerID" not-null="true" />
</key>
<one-to-many class="MyNamespace.OwnerLifeRelationship, MyAssembly"/>
</bag>
一个例子是有2个名为Jim和Jean的Live和一个名为Bill的所有者,而Bill有2个OwnerLifeRelationship孩子:Jean的父亲和Jim的雇主。
问题在于,域层的各个部分可能会因为各种业务规则而隐式地从Lifes的Policy集合中删除Life。当发生这种情况时,我需要确保在保存删除Life之前首先删除Life和Owners之间的任何关系,否则我会收到外键违规。但似乎我需要删除相关所有者的关系,并在删除Life之前首先保存策略,然后再次保存策略。如果我一次性保存,NHibernate会抛出:
无法将值NULL插入“LifeID”列,表'OwnerLifeRelationship';列不允许空值。更新失败。
除了做两次保存的不愉快之外,我认为无论如何我都不能,因为这个逻辑被封装在一个持久性无知的域层中。
有没有办法在NHibernate映射文件中设置这个域关系,以便NHibernate在删除所有者关系后可以透明地处理Life的删除?我确实尝试在Life和Owner上设置Relationships包,但这导致异常“已删除的对象将通过级联重新保存(从关联中删除已删除的对象)”。
更新:我试图通过将OwnerLifeRelationship中的NHibernate映射移除到Life并将其作为LifeID暴露在OwnerLifeRelationship类上而不是作为映射的Life对象来简化问题。然后我在Policy.Lives上添加了一个集合更改处理程序,对于删除的任何Life,我遍历Policy.Owners并删除所有者和删除的Life之间定义的所有OwnerLifeRelationship。所以现在OwnerLifeRelationship映射文件的相关部分是:
<many-to-one
name="Owner"
class="MyNamespace.Owner, MyAssembly"
column="OwnerID"
access="field.camelcase-underscore">
</many-to-one>
<property name="LifeID"
type="System.Guid"
not-null="true" />
但这仍然会导致外键违规。我已经确认集合已更改处理程序逻辑会导致在保存发生之前删除所有必需的关系,但我可以在NHibernate发出的SQL中看到,在删除之前,OwnerLifeRelationships 不已删除生命被发布 - 因此存在问题。