nHibernate - 类中的对象或ObjectID

时间:2010-12-05 04:40:20

标签: c# nhibernate domain-driven-design nhibernate-mapping

我们正在迁移当前的C#应用​​程序以使用nHibernate。由于nHibernate提升了纯域驱动设计,我们可以将业务对象添加为类的属性,或者继续使用ID。

让我用一个例子来说明这一点;

参加以下现有课程。地址(和子项)仅由其ID标识。

public class Person
{
    public int PersonID { get; set; }
    public string FirstName { get; set; }
    public string FirstName { get; set; }
    public int AddressID { get; set; }
    public List<int> ChildrenIDs { get; set; }
}

当我们将类转换为使用nHibernate时,我们还希望借此机会更改“Person”类的结构以更好地满足需求。希望nHibernate能够“在幕后”处理所有数据检索

public class Person
{
    public virtual int PersonID { get; private set; }
    public virtual string FirstName { get; set; }
    public virtual string FirstName { get; set; }
    public virtual AddressObject Address { get; set; }
    public virtual List<ChildrenObject> Children { get; set; }
}

我们现在为Person存储一个Address对象和一个Children对象列表。这对我们的业务需求更好,因为我们在访问类时拥有所有信息,我们可以不使用ID,而是使用底层对象。

在这种情况下,nHibernate会为Person.Address持续什么?它是否只会持久保存在Person表中为该对象指定的唯一ID?那么儿童对象呢?

2 个答案:

答案 0 :(得分:5)

您应该使用域对象作为属性,例如您给出的第二个示例。

NHibernate将保留一个唯一的AddressObject。大概AddressObjectPerson类之间存在一对多的关系,因此List类中应该有PersonAddressObject代表住在那里的Persons。此关系也应在AddressObject.hbm.xml文件中定义,如下所示:

<set name="persons" cascade="all" inverse="true" lazy="true">
    <key column="address_id"/>
    <one-to-many class="Person"/>
</set>

在Person.hbm.xml中,像这样:

<many-to-one name="address"
    class="AddressObject"
    column="address_id"/>

另外,为什么要有专门针对儿童的课程?如果您的意思是儿童的字面定义,为什么不仅仅为此目的使用Person类?

答案 1 :(得分:0)

有两种基本DDD类型的感兴趣对象;实体或ValueObject。您或者更确切地说,您的域确定了上下文,该上下文指出哪个类型的对象是实体,哪个是ValueObject。

如果某个对象显然是一个实体,那么你应该总是让你的生活变得更轻松,并使用某种代理ID来保持它,即使id在你的对象模型中没有任何意义。创建一个EntityBase类,它为您提取Id的详细信息,并从中继承Person和其他实体。

地址很有趣,因为某些域是实体而其他域是ValueObject。如果你认为它是一个Value Object,那么将它映射为NHibernate中的一个组件。

NHibernate处理所有不幸的细节,这些细节围绕着持久化对象与内存中对象完全不同的事实。

HTH,
Berryl