如何让 NHibernate 以一对一的关系删除孤儿
本文关键字:关系 删除 一对一 NHibernate | 更新日期: 2023-09-27 17:57:09
我们的模型中有一个对象,称之为类X。在我们的模型中还有其他几个类,它们将类 X 的实例作为属性,称为 A、B、C 等。这本质上是一个一对一的映射,因为每个 X 只能属于一个父类。为了在数据库端映射这种关系,我们当前使用外键到表 A、B 和 C 中的 X 表。对于 NHibernate 映射,我们目前正在 A、B 和 C 类的映射中使用:
ManyToOne(a => a.X, m => m.Cascade(Cascade.All));
这主要用于保存、检索和更新我们的 X 类 - 我们在让 NHibernate OneToOne
映射正常工作时遇到了很多问题。问题是,当你采用持久类 A 并将其 X 替换为 X 的新实例,然后保存该 A 实例时,新的 X 实例将写入数据库,A 列中的外键将更新,但旧的 X 不会被删除,所以我们现在有一个孤立的 X。
我们希望自动删除这些孤立的 X。我们希望 NHibernate 这样做,因为 X 是一个复杂的类,它与我们已经设置级联以正确处理的其他表有许多自己的关系 - 我设置了一个 SQL 脚本来正确删除孤立的 X,它大约有 50 行长。
我们试图避免涉及将类 X 中的引用放在其父项的解决方案,因为它总共可以属于 5 个类,并且类 A 有一个 X,类 B 在命名属性中有 2 个 X 等情况。
到目前为止我尝试过的事情:
将DeleteOrphans
添加到ManyToOne
映射 - 不起作用
OneToOne
映射 - 真的希望键在另一个表中,并且似乎不支持级联删除。
还考虑:
NHibernate似乎不支持设置某种甚至在更新或删除发生时触发
显然,只有OneToMany
和ManyToMany
映射支持DeleteOrphans
,因此,我可以使实际属性使用某种列表或集合,并使用getter和setters使其看起来像模型其余部分的普通属性。听起来很笨拙,可能需要在 X 中引用其他类。
数据库触发器 - 我还没有真正检查SQL Server触发器是否可以以这种方式使用,但这听起来是一个非常尴尬的解决方案。
有人对如何完成这项工作有任何想法吗?
我们最终采用的解决方案是永远不允许将 X 的新实例分配给任何保存它的类。相反,我们向 setter 添加了代码,以便每当您尝试分配 X 的新实例时,它实际上会清除现有 X 的内容,并将它们全部替换为新 X 的内容。由于 X 中包含的所有对象都是集合,因此 NHibernate 级联删除在删除 X 的旧子项并将其替换为新子项时正常工作。这是一个有点丑陋的解决方案,但这是我们能想出的最不丑陋的东西。