如果我只更改该集合中的一个元素,如何强制NHibernate不为集合中的每个元素生成UPDATE。这是:
internal class Master
{
private int _id;
public string Name { get; set; }
public ISet<Slave> Slaves { get; set; }
public Master()
{
Slaves = new HashedSet<Slave>();
}
}
internal class Slave
{
private int _id;
public string Name { get; set; }
public Master Master { get; set; }
}
映射:
<class name="nHibernateTutorials.Slave, nHibernateTutorials" lazy="false">
<id access="field" name="_id" column="id">
<generator class="native"/>
</id>
<property access="property" name="Name" column="name"/>
<many-to-one access="property" name="Master" column="master"/>
</class>
<class name="nHibernateTutorials.Master, nHibernateTutorials" lazy="false">
<id access="field" name="_id" column="id">
<generator class="native"/>
</id>
<property access="property" name="Name" column="name"/>
<set access="property" name="Slaves" cascade="save-update">
<key column="master"/>
<one-to-many class="nHibernateTutorials.Slave, nHibernateTutorials"/>
</set>
</class>
更新集合元素的代码:
Master m = new Master {Name = "Kenny"};
Slave s1 = new Slave { Name = "Cartman", Master = m};
m.Slaves.Add(s1);
Slave s2 = new Slave {Name = "Kyle", Master = m};
m.Slaves.Add(s2);
Slave s3 = new Slave {Name = "Stan", Master = m};
m.Slaves.Add(s3);
DbManager.SaveObject(m);
s1.Name = "Daisy";
DbManager.SaveObject(m);
DbManager.SaveObject中的代码只是打开新会话并使用SaveOrUpdate来更新对象。
如果我从Slaves集合中更改其中一个元素然后尝试更新master,NHibernate会生成SQL以更新Slaves集合中的所有元素。但我只需要更新一个元素。
谢谢。
答案 0 :(得分:1)
您可能会看到多余的多对一更新。在映射一对多集合时,必须选择哪一方是该关系的所有者。在您的示例中,关系的两个方面都认为他们拥有它!
您需要使用inverse="true"
向您的set元素添加属性。该指令告诉NHibernate不要从关系的那一端更新集合。
答案 1 :(得分:0)
尝试使用access =“backfield”而不是access =“property”。
答案 2 :(得分:0)
您正在重建瞬态集合,因为Master.Slaves仍然是原始集合。
这不会在新会话中发生。
如果要在保存后更新同一会话中的实体,则应该session.Refresh()该实体。您的DBManager.SaveObject方法可以在保存后进行刷新。
DbManager.SaveObject<T>( T entity )
{
session.Save( entity );
session.Refresh( entity );
}