如何让NHibernate以一对一的关系删除孤儿?

时间:2014-04-07 22:28:06

标签: c# nhibernate mapping-by-code

我们的模型中有一个对象,称之为类X.我们的模型中有几个其他类有一个类X的实例作为属性,称它们为A,B,C等。这本质上是一个一对一映射,因为每个X只能属于一个父类。要在数据库端映射此关系,我们当前正在使用表A,B和C中的X表的外键。对于NHibernate映射,我们当前正在使用,在A,B和C的映射中类:

ManyToOne(a => a.X, m => m.Cascade(Cascade.All));

这主要用于保存,检索和更新我们的类Xs - 我们在使NHibernate OneToOne映射正常工作时遇到了很多问题。问题是,当您获取持久化类A并将其X替换为新的X实例然后保存该实例时,新的X实例将被写入数据库并且A列中的外键会更新,但旧的X不会被删除,所以我们现在有了一个孤儿X.

我们希望自动删除那些孤立的Xes。我们希望NHibernate这样做,因为X是一个复杂的类,它有许多自己的关系,我们已经设置了正确处理的级联 - 我有一个SQL脚本设置为正确删除孤立Xes,它大约是50线条很长。

我们试图避免涉及将类X中的引用放入其父项的解决方案,因为它可以属于总共5个类,并且诸如类A的情况具有一个X,类B具有2命名属性中的Xes等

到目前为止我尝试过的事情:

DeleteOrphans添加到ManyToOne映射 - 不起作用

OneToOne映射 - 确实希望密钥位于另一个表中,并且似乎不支持级联删除。

还考虑过:

NHibernate似乎没有任何支持设置甚至在更新或删除等事情发生时触发

显然,只有OneToManyManyToMany映射支持DeleteOrphans,因此,我可以使实际属性使用某种列表或集合,并使用getter和setter来实现它看起来像是模型其余部分的正常属性。听起来非常h​​acky,它可能需要在X中引用其他类。

数据库触发器 - 我还没有真正检查过SQL Server触发器是否可以这种方式使用,但这听起来像是一个非常尴尬的解决方案。

有没有人对如何使这项工作有任何想法?

1 个答案:

答案 0 :(得分:0)

我们最终使用的解决方案是永远不允许将新的X实例分配给任何持有它的类。相反,我们已经向setter添加了代码,这样,每当你尝试分配一个新的X实例时,它实际上会清除现有X的内容并用新X的内容替换它们。因为所有的对象都是如此。包含在X中的是集合,NHibernate级联删除正确删除X的旧子项并用新的替换它们。这是一个丑陋的解决方案,但它是我们能够提出的最不可靠的事情。