0

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

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

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

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

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

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

添加DeleteOrphansManyToOne映射 - 不起作用

OneToOne映射 - 真的希望密钥在另一个表中,并且似乎不支持级联删除。

还考虑了:

NHibernate 似乎不支持设置某种甚至在发生更新或删除等事情时触发

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

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

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

4

1 回答 1

0

我们在这里最终采用的解决方案是永远不允许将 X 的新实例分配给任何持有它的类。相反,我们在 setter 中添加了代码,这样,每当您尝试分配 X 的新实例时,它实际上会清除现有 X 的内容并将它们全部替换为新 X 的内容。由于所有对象X 中包含的是集合,NHibernate 级联删除在删除 X 的旧子项并用新子项替换它们时正常工作。这是一个有点丑陋的解决方案,但它是我们能够想出的最不丑陋的东西。

于 2014-05-01T19:16:36.203 回答