使用NHibernate时,在什么情况下你会选择使用复合元素映射集合来提供值对象的集合,而不是创建一个完整的实体并使用一对多映射它?
您可能有一个值类型类'PostalAddress'来表示地址。如果您有一个人实体,并且每个人可以拥有许多地址,您可以像这样映射这种关系(选项1):
<bag name="Addresses" table="PersonAddress">
<key column="PersonID"/>
<composite-element class="PostalAddress">
<property name="StreetAddress"/>
<property name="Town"/>
<property name="City"/>
<property name="Postcode"/>
</composite-element>
</bag>
或者您可以创建一个实体'PersonAddress',其上有一个'PostalAddress'类型的属性,并使用一对多关联映射地址(选项2):
<bag name="Addresses">
<key column="PersonID"/>
<one-to-many class="PersonAddress"/>
</bag>
<class name="PersonAddress">
<id name="Id">
<generator class="native"/>
</id>
<component name="Address" class="PostalAddress">
<property name="StreetAddress"/>
<property name="Town"/>
<property name="City"/>
<property name="Postcode"/>
</component>
</class>
有没有理由不做选项1? PersonAddress表有ID列的事实是否应该是一个实体本身,因此使用选项2?
答案 0 :(得分:19)
&lt;复合-组件&gt;当你有一个值的集合,而&lt;一对多&gt;是一组实体。实体的定义特征是唯一标识符。因此,如果您的集合中的项目具有PK,请使用&lt; one-to-many&gt;。否则使用&lt; composite-element&gt;。
另一种思考方式是如何确定平等。您是通过比较ID还是通过验证所有属性是否相同来确定相等性?例如在您的应用程序中,如果(address1.Id == address2.Id)或if(address1.Street == address2.Street&amp;&amp; address1.City == address2.City&amp;&amp; etc等),请将两个对象表示相同的地址。)?没有通用的正确答案,因为它取决于应用程序上下文。在许多情况下,金钱是一个价值对象。无论你有20美元还是20美元,都没关系。只有金额是相关的。如果您正在为薄荷编写跟踪应用程序,他们可能需要知道您正在处理哪个20美元的账单,并且您将在20美元的账单上跟踪序列号。在这种情况下,货币是一个实体。这一切都取决于应用和背景...