我在我的应用程序中使用NHibernate并具有以下情况。 (请注意,为了便于理解,这里的情况要简化得多)
从数据库中查询对象。它使用Session.Update()
进行编辑和更新。然后在提交事务之前从会话中逐出该对象(使用Session.Evict(obj)
)。预期的结果是更改将持久保存到数据库中。
当我将Id
列作为NHibernate identity
列时,以前工作正常。
最近,我们将Id列更改为非身份。因此,除非我在Evict之前明确调用Session.Flush()
,否则上述方案不会持久存储到数据库中。
有人能指出/向我解释这种行为的原因吗?
这个链接,NHibernate Session.Flush & Evict vs Clear,提及有关Evict和标识栏的内容,对我来说不太清楚。
答案 0 :(得分:9)
您的工作流程不正确。
首先,当您从数据库中检索对象时,session.Update(entity)
不会执行任何操作。更改将自动在Flush/Commit
接下来,Evict
删除会话对该对象的所有知识,因此它不会保留对其应用的任何更改。在正常情况下,您几乎不应该使用此方法,这使我认为您没有正确处理会话。
第三,使用identity
导致插入在Save
上立即发生的事实是一种限制,而非功能。
正确的工作流程是:
using (var session = factory.OpenSession())
using (var transaction = session.BeginTransaction())
{
var entity = session.Get<EntityType>(id);
entity.SomeProperty = newValue;
transaction.Commit();
}
完全结构(using
语句等)可以在桌面应用程序中更改,但基本思路是相同的。
答案 1 :(得分:2)
标识强制NHibernate立即将实体保存到数据库session.Save()
非标识允许它批量插入以将它们作为整体发送。 Evict将从会话中删除对象的所有信息。因此,即使会话不知道,它在身份上也会忘记它已经在数据库中的实体。
补救你可以
Flushmode.Auto
(强制立即冲洗)session.Flush()
Evict
哪个是最佳选择取决于上下文