NHibernate:多对多集合

时间:2011-08-19 05:37:23

标签: nhibernate nhibernate-mapping

客户可以有多个联系人。下面的代码正在运行,但......首先删除此客户的联系人,然后再次插入。是不是可以避免这种删除而只是插入新的?

<class name="Customer" table="Customer">
    <id name="Id">
        <generator class="native" />
    </id>
    <property name="LastName" not-null="true" />

    <bag name="Contacts" cascade="all-delete-orphan" table="CustomerContact">
        <key column="Customer" not-null="true" />
        <many-to-many class="Contact"/>
    </bag>l
</class>

<class name="Contact" table="Contact">
    <id name="Id">
      <generator class="native" />
    </id>
    <property name="LastName" not-null="true" />

    <many-to-one name="Customer" column="Customer" not-null="true" />
</class>

public virtual void AddContact(Contact contact)
{
    Contacts.Add(contact);
    contact.Customer = this;
}

当我执行此代码两次时,添加2个联系人:

Contact contact = new Contact() { LastName = "MyLastName" };
Customer customer = session.Get(customerId);
customer.AddContact(contact);
session.Update(customer);

enter image description here

2 个答案:

答案 0 :(得分:2)

您正在为集合使用bag,包可以包含重复项,不维护订单,并且无法使用SQL明确标识包中的单个条目。

这就是NH移除并插入所有已分配实体的原因。如果符合您的要求,请使用set

答案 1 :(得分:1)

当NH丢失有关集合的持久性信息时,通常会发生这种情况。它假设您更改了整个集合。要有效地更新数据库,它会删除一个查询中的所有项目(删除...其中customer = 5)并插入新项目。

您可能不会返回NH提供的收藏品。

典型错误:

  IList<Contact> Contacts
  {
    get { return contacts; }
    // wrong: creates a new List and replaces the NH persistent collection
    set { contacts = value.ToList(); }
  }

顺便说一句,你应该使集合反向,因为它是联系人的冗余。客户关系:

<bag name="Contacts" cascade="all-delete-orphan" table="CustomerContact" inverse="true">
    <key column="Customer" not-null="true" />
    <many-to-many class="Contact"/>
</bag>