由于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);
答案 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”,在各种条件下触发刷新。
在这种情况下适合我的解决方案是:
将Session FlushMode设置为'Commit'。
删除处理对象内存更新的代码中对“Flush”的所有引用。
“保存”时,每个会话只能打开1个事务,然后丢弃该会话。