使用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?
1 回答
<composite-element>适用于具有值集合的情况,而<one-to-many>是实体集合 . 实体的定义特征是唯一标识符 . 因此,如果集合中的项目具有PK,请使用<one-to-many> . 否则使用<composite-element> .
另一种思考方式是如何确定平等 . 您是通过比较ID还是通过验证所有属性是否相同来确定相等性?例如在你的应用程序中,如果(address1.Id == address2.Id)或if(address1.Street == address2.Street && address1.City == address2.City && etc.等),两个对象是否代表相同的地址?没有通用的正确答案,因为它取决于应用程序上下文 . 在许多情况下,金钱是一个 Value 对象 . 无论你有20美元还是20美元,都没关系 . 只有金额是相关的 . 如果您正在为薄荷编写跟踪应用程序,他们可能需要知道您正在处理哪个20美元的账单,并且您将在20美元的账单上跟踪序列号 . 在这种情况下,货币是一个实体 . 这完全取决于应用和背景......