【发布时间】:2010-01-09 04:52:33
【问题描述】:
我有两个这样的实体(仅提炼出相关的内容):
public class Person {
public virtual Address Address
}
public class Address {
}
Person 与 Address 具有多对一关系,或者在对象方面,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 也引用它。
在数据库方面,没有垃圾收集的概念。对数据库来说,只有一对多或多对多的关系,或者换句话说,一个父级和一个子级的集合。回到Person和Address,我们看到这是从Address到Person的一对多关系(每个人只能有一个地址,但一个地址可以属于很多人,例如作为一个拥有共同地址的人的家庭)。数据库将Address 视为父级,将Person 视为子级的集合。因此,通过删除Person,Address 也不应该被删除是有道理的(换句话说,如果你有一个书架收藏着书籍,删除一本书不应该删除书架)。
那么我们该如何解决这个问题呢?我们将不得不删除其子集合为空的所有父级。在这种情况下,应删除具有空集合Persons 的Address。这是一个业务规则,因为没有任何内容表明 Address 不能单独存在,但是在我正在开发的应用程序中,如果 Address 本身没有附加到一个人身上,那么它本身就没有任何意义,因此应该被淘汰。但是,在其他 Person 出现并引用它之前,该地址完全有可能保持孤立状态。
【问题讨论】:
标签: nhibernate nhibernate-mapping many-to-one