如何在NHibernate会话中恢复所有更改?

时间:2009-09-07 20:10:11

标签: nhibernate

由于NHibernate ISession跟踪更改,我想知道是否可以丢弃会话中的所有更改,如下所示:

class Person
{
    public virtual string Name { get; set; }
}

// Somewhere else...
var session = sessionFactory.OpenSession();
person.Name = "John Doe";
using(var tx = session.BeginTransaction)
{
    session.Save(person);
    tx.Commit();
}

person.Name = "Jane Doe";
// Now, can I do something like this?
session.RevertAll();
Assert.AreEqual("John Doe", person.Name);

4 个答案:

答案 0 :(得分:4)

NH不会还原您在实体中所做的更改。业务逻辑负责关心实体的状态。

“撤消”更改的最安全方法是:回滚事务,清除(或重新创建)会话并从头开始。

会话中有一个Reload方法。它将数据库中的状态重新加载回实体。但这对于这种情况不起作用,因为NH可能已经刷新了一些变化,例如。在执行查询之前。 (它适用于分离的实体。)

答案 1 :(得分:2)

 session.Refresh(entity); // Cancel object changes, and changes of object collections

取消编辑所有对象:

 var e = ((SessionImpl)session).PersistenceContext.EntityEntries;
 var allEntities = e.Keys.Cast<object>().ToList();
 foreach (var entity in allEntities)
      session.Refresh(entity);
 //Maybe it's not a good practice...

答案 2 :(得分:1)

session.Clear()

使用session.Clear,NHibernate会话将不再包含任何脏对象。但是,这并不意味着你的断言会起作用。 NHibernate不会还原对象本身的状态。 为了实现这一点,我必须自己实现可撤销支持。 (您可以查看IEditableObject界面。)

但是,一旦您保存并提交/刷新,则更改已进入您的数据库。 session.Clear不会在场外恢复这些变化。

答案 3 :(得分:0)

尝试将会话刷新模式设置为Commit。

session.FlushMode = FlushMode.Commit;

未分离时,数据对象处于“瞬态”或“持久”状态。

瞬态对象是新对象,将导致INSERT语句 明确保存时。持久对象是在刷新会话时将导致UPDATE语句的对象(即使您没有在该对象上调用SaveOrUpdate)。

当会话需要将内存中对象容器与数据库同步时,会发生刷新。发生刷新时,无论是否在其上调用SaveOrUpdate,都会刷新所有PERSISTED内存中对象(具有内存中更改)。根据会话的“FlushMode”,在各种条件下触发刷新。

在这种情况下适合我的解决方案是:

  1. 将Session FlushMode设置为'Commit'。

  2. 删除处理对象内存更新的代码中对“Flush”的所有引用。

  3. “保存”时,每个会话只能打开1个事务,然后丢弃该会话。