当NHibernate中的引用更改时,如何删除引用对象?

当NHibernate中的引用更改时,如何删除引用对象?,nhibernate,nhibernate-mapping,many-to-one,Nhibernate,Nhibernate Mapping,Many To One,我有两个这样的实体(仅提炼出相关的实体): 人与地址存在多对一关系,或者在对象术语中,人引用地址,并且此链接是单向的(地址没有引用回人) 现在,如果我使用此代码: // save a new person with a new address var person = new Person(); person.Address = new Address(); person.Save(); // change the person's address and save it again pers

我有两个这样的实体(仅提炼出相关的实体):

地址
存在多对一关系,或者在对象术语中,
引用
地址
,并且此链接是单向的(
地址
没有引用回

现在,如果我使用此代码:

// save a new person with a new address
var person = new Person();
person.Address = new Address();
person.Save();

// change the person's address and save it again
person.Address = new Address();
person.Save();
第一部分做它应该做的,它在数据库中创建一个新的
和一个新的
地址

但是,第二部分将更新现有的
人员
,并创建一个新的
地址
,但不会删除现在孤立的第一个地址。为了让NHibernate认识到我正在更改对新实体的引用并自动“垃圾收集”孤立实体,我必须做什么?还是我必须手动执行此操作

可能的解决办法 虽然我没有确凿的证据证明这确实是在发生什么,我认为这个问题的原因是因为对象关系阻抗不匹配。在编程中,我们知道对象包含对其他对象的引用,一旦这些引用丢失,垃圾收集就会来删除那些不再有任何指向它们的引用的“孤立”对象。在我提供的示例中,
Person
引用了
Address
,一旦对
Address
的引用丢失,它将被垃圾收集,假设没有其他
Person
也引用它

在数据库方面,没有垃圾收集的概念。对于数据库,只有一对多或多对多关系,或者换句话说,一个具有子集合的父关系。回到
地址
,我们看到这是从
地址
的一对多关系(每个人只能有一个地址,但一个地址可以属于许多人,例如共享一个共同地址的家庭)。数据库将
地址
父对象和
视为子对象的集合。因此,通过删除
,也不应该删除
地址
(换句话说,如果你有一个书架上有一本书,那么删除一本书不应该删除书架)


那么我们如何解决这个问题呢?我们必须删除其子集合为空的所有父集合。在这种情况下,应删除
地址
,其中
人员的集合为空。这是一条业务规则,因为没有任何规定说明
地址本身不能存在,但在我开发的应用程序中,
地址本身如果没有附加到某个人,则意味着什么,因此应该删除它。但是,地址完全有可能保持孤立状态,直到其他人出现并引用它。

在关系上设置cascade=“all delete orphan”

在NHibernate中,没有合理的方法可以做到这一点,即使您从一个(地址)端映射关系。这相当于要求在对象的一个子集合为空时自动删除该对象。在你可能的解决方案中,我没有遵循你的想法,但你是对的,这是一条商业规则

当然,要做到这一点,有“糟糕”的方法。如果数据库中存在外键约束,则可以在更改引用时删除地址并接受异常。如果删除成功,则它是孤立的,否则仍有人引用它


地址通常位于关系的多个方面,即一个人可以有多个地址。国际海事组织认为,这是一个更好的办法。地址表中确实有重复的地址,但这是重复数据,而不是重复数据。

我已经尝试过了。虽然它可以用于删除父实体(在本例中为
Person
对象),但如果您将子实体更改为新实体,它将不起作用。旧数据将保持孤立状态。重复数据和重复数据之间有什么区别?
// save a new person with a new address
var person = new Person();
person.Address = new Address();
person.Save();

// change the person's address and save it again
person.Address = new Address();
person.Save();