我们正在迁移当前的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?那么儿童对象呢?
答案 0 :(得分:5)
您应该使用域对象作为属性,例如您给出的第二个示例。
NHibernate将保留一个唯一的AddressObject
。大概AddressObject
与Person
类之间存在一对多的关系,因此List
类中应该有Person
类AddressObject
代表住在那里的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