客户可以有多个联系人。下面的代码正在运行,但......首先删除此客户的联系人,然后再次插入。是不是可以避免这种删除而只是插入新的?
<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);
答案 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>