我想知道在什么情况下以下NHibernate代码可能会失败: var session = NHibernateSessionManager.CurrentSession;var foo = session.LinqFoo.ToList()[0];foo.SomeProperty = "test";session.SaveOrUpdate(foo);var reloadedFoos = sessio
var session = NHibernateSessionManager.CurrentSession; var foo = session.Linq<Foo>.ToList()[0]; foo.SomeProperty = "test"; session.SaveOrUpdate(foo); var reloadedFoos = session.Linq<Foo> .Where(x => x.SomeProperty == "test"); Assert.That(reloadedFoos.Count > 0);
Assert语句总是失败.
如果我在SaveOrUpdate之后手动调用session.Flush,那么select查询会成功,但是我认为我们不必手动调用flush?我的理解是NHibernate应该足够聪明才能意识到Foo已经更新,所以第二个选择查询应该成功.
观察生成的SQL,看起来第二个选择查询的SQL在第一个SaveOrUpdate的sql之前执行.
实际上,如果我将整个方法包装在一个事务中,那么它会成功:
using(NHibernateSessionManager.CurrentSession.BeginTransaction() { // Same code as above }
现在SaveOrUpdate的sql将在Linq.Where sql之前执行.这有点奇怪,因为我甚至不必在两者之间提交交易.
到底是怎么回事?
我建议你利用NHibernate事务.完全可能的是,在没有使用它们的情况下,NHibernate无法确定何时发出SaveOrUpdate调用.您会发现即使是只读语句在使用事务时也能表现得更好.有关详细信息,请参阅http://nhprof.com/Learn/Alert?name=DoNotUseImplicitTransactions.
例如:
using(var session = NHibernateSessionManager.CurrentSession) { using(var transaction = session.BeginTransaction()) { var foo = session.Linq<Foo>.ToList()[0]; foo.SomeProperty = "test"; session.SaveOrUpdate(foo); transaction.Commit(); } }