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

时间:2010-01-09 04:52:34

标签: nhibernate nhibernate-mapping many-to-one

我有两个这样的实体(只提炼到相关内容):

public class Person {
    public virtual Address Address
}

public class Address {
}

PersonAddress具有多对一关系,或者在对象术语中,Person引用Address,此链接是单向的( Address没有对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();

第一部分完成它应该做的事情,它在数据库中创建一个新的Person和一个新的Address

但是,第二部分将更新现有的Person并创建一个新的Address,但它不会删除现在的孤立的第一个地址。我需要做些什么才能让NHibernate认识到我正在改变对新实体的引用并自动“垃圾收集”孤立实体?或者我必须手动执行此操作吗?

可能的解决方案

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

在数据库方面,没有垃圾收集的概念。对于数据库,只有一对多或多对多的关系,换句话说,就是具有子集合的父对象。回到PersonAddress,我们发现这是从AddressPerson的一对多关系(每个人只能有一个地址,但是地址可以属于很多人,例如共享地址的人的家庭。数据库将Address父项和Person视为子项集合。因此,有意义的是,删除Person时,Address也不应该被删除(换句话说,如果你有一个带有书籍集合的书架,删除一本书不应该删除书架)。

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

2 个答案:

答案 0 :(得分:1)

在关系

上设置cascade =“all-delete-orphan”

答案 1 :(得分:1)

在NHibernate中没有合理的方法可以做到这一点,即使您从一个(地址)方面映射关系。它等同于在其子集合之一为空时要求自动删除对象。我不会在你可能的解决方案中按照你的想法,但你是对的,这是一个商业规则。

当然,有“坏”方法可以实现这一目标。如果数据库中存在外键约束,则可以在更改引用时删除地址并吞下该异常。如果删除成功,那么它就是一个孤儿,如果没有,那么仍有人引用它。

地址通常位于关系的许多方面,即Person可以有多个地址。这是一种更好的方法。您最终会在地址表中找到重复的地址,但这会重复数据而不是重复数据。