当前位置 : 主页 > 编程语言 > c语言 >

c# – NHibernate没有发现变化

来源:互联网 收集:自由互联 发布时间:2021-06-25
我想知道在什么情况下以下NHibernate代码可能会失败: var session = NHibernateSessionManager.CurrentSession;var foo = session.LinqFoo.ToList()[0];foo.SomeProperty = "test";session.SaveOrUpdate(foo);var reloadedFoos = sessio
我想知道在什么情况下以下NHibernate代码可能会失败:

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();
  }
}
网友评论