我有两个这样的实体(很简化):
public Test1 {
public virtual int Id {get;set;}
public virtual ICollection<Test2> Childs {get;set;}
}
public Test2 {
public virtual int Id {get;set;}
public virtual Test1 Parent {get;set;}
public virtual string Name {get;set;}
}
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="Test" assembly="Test">
<class name="Test1" table="test1">
<id name="Id" column="id_parent">
<generator class="native" />
</id>
<set name="Childs" table="test2" cascade="save-update" batch-size="10" inverse="true">
<key column="id_parent" not-null="true"/>
<one-to-many class="Test.Test2, Test" />
</set>
</class>
</hibernate-mapping>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="Test" assembly="Test">
<class name="Test2" table="test2">
<id name="Id" column="id_child">
<generator class="native" />
</id>
<many-to-one name="Parent" column="id_parent" class="Test.Test1, Test" />
<property name="Name" column="name" />
</class>
</hibernate-mapping>
现在我想更改(第一个)子项的名称属性:
var entities = Session.CreateCriteria<Test1>().List<Test1>();
var tx = Session.BeginTransaction();
foreach (Test1 entity in entities)
{
entity.Childs.First().Name = "blabla";
Session.Update(entity);
}
tx.Commit();
但这不起作用。我可以在NhProf中看到事务已经启动,sql被用于获取父记录,另一个用于获取子记录。但是没有为更新name属性而触发sql。我究竟做错了什么?我在阅读文档时尝试了不同的事情,但没有成功。
非常感谢提前!
答案 0 :(得分:0)
ISession.Update
。您正在使用附加实体,因此会自动跟踪更改。无需显式调用Update。
请阅读此处以获得进一步说明:
http://www.nhforge.org/doc/nh/en/index.html#manipulatingdata-updating-detached
此外,它取决于您的flushmode设置为何时更新。尝试在上面的示例中将flushmode显式设置为Commit。这是一个flushmodes表:
自动强>
在查询执行之前,有时会刷新ISession,以确保查询永远不会返回失效状态。这是默认的刷新模式。
<强>提交强>
调用Transaction.Commit()时,将刷新ISession
<强>从不强>
除非应用程序显式调用Flush(),否则永远不会刷新ISession。此模式对于只读事务非常有效
所以你最终会得到这样的东西:
Session.FlushMode = FlushMode.Commit;
var entities = Session.CreateCriteria<Test1>().List<Test1>();
using(var tx = Session.BeginTransaction())
{
foreach (Test1 entity in entities)
{
entity.Childs.First().Name = "blabla";
Session.Update(entity);
}
tx.Commit();
}
答案 1 :(得分:0)
我遇到了类似的问题,并通过删除inverse
属性解决了这个问题。你有inverse=true
。尝试将其更改为false
。