NHibernate:为什么要使用<composite-element>而不是<one-to-many>来映射集合</one-to-many> </composite-element>

时间:2010-11-30 13:58:31

标签: nhibernate nhibernate-mapping

使用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 个答案:

答案 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美元的账单上跟踪序列号。在这种情况下,货币是一个实体。这一切都取决于应用和背景...