在将整个系统从NH1.2升级到NH3.3的过程中。系统中的一个常见场景(由以前的开发人员)是分离多个对象并将它们存储在 Web 会话中,然后通过 IHttpModule 在每个请求时附加它们。
在运行 NHProf 的简单页面加载中,我注意到现在附加的这些对象导致触发它们在数据库中更新,尽管它们尚未更改。
要附加的先前代码 (NH1.2) 如下:
if (((NHibernate.Impl.SessionImpl)session).已保存(obj) 会期。Lock(obj, LockMode.None)
由于似乎IsSave已被删除,因此代码现在为:
if (obj != null) 会期。Lock(obj, LockMode.None)
我的理解是LockMode.None不应该导致数据库更新。某些对象具有版本,而其他对象则没有。 两者都正在更新。
任何建议不胜感激。
我想我会通过类比来解释,看看区别:
var obj = _nhibernateSession.Load<MyObject>(id);
obj.Title = "Some Title";
_nhibernateSession.Transaction.Commit();
和
var obj = someObjectInMemoryNotInSession as MyObject;
obj.Title = "Some Title";
_nhibernateSession.Update(obj);
_nhibernateSession.Transaction.Commit();
您是否注意到了区别:在第一种情况下,不需要更新,因为 obj 是从会话中获取的,会话将知道它的任何更改,但在第二个示例中,我们需要显式调用 Update,因为现在我们的 obj 已从会话中分离。
现在回答您的问题:声明:
if (((NHibernate.Impl.SessionImpl)session).IsSaved(obj)
session.Lock(obj, LockMode.None)
在 NH1.2 中运行良好,因为通过这种方式,您处于第一种情况(从会话加载实体时的情况),但现在您是第二种方法:
if (obj != null)
session.Lock(obj, LockMode.None)
并且它不会从会话加载 obj,这就是 NHibernate 触发数据库更新的原因。
如果你想避免这种情况,只需在以下情况下调用 Get():
obj = session.Get(id, LockMode.None);
或者简单地:
obj = session.Get(id);
两者都将为您的案件完成工作。