NHibernate提交数据库更改,无需显式调用保存或更新

NHibernate提交数据库更改,无需显式调用保存或更新,nhibernate,Nhibernate,我在ASP.NET中使用NHibernate2.0。 我在页面请求时启动事务,并在最后提交事务。 在页面中: -我得到一个物体 -我更改对象属性 -我验证对象 -如果验证正常,我调用该对象的保存更新 -如果验证错误,我不会对该对象进行任何调用以保存更新 -我总是在页面末尾提交事务 问题是,当验证错误,并且我没有在对象上进行任何保存更新的调用时,提交事务会在数据库中提交更改 我将FlushMode设置为“永不改变,但不改变” 你有什么建议吗?我错了什么 在页面中:-我得到一个对象 如果您从会话中获

我在ASP.NET中使用NHibernate2.0。 我在页面请求时启动事务,并在最后提交事务。 在页面中: -我得到一个物体 -我更改对象属性 -我验证对象 -如果验证正常,我调用该对象的保存更新 -如果验证错误,我不会对该对象进行任何调用以保存更新 -我总是在页面末尾提交事务

问题是,当验证错误,并且我没有在对象上进行任何保存更新的调用时,提交事务会在数据库中提交更改

我将FlushMode设置为“永不改变,但不改变”

你有什么建议吗?我错了什么

在页面中:-我得到一个对象

如果您从会话中获取对象,则您正在进行更新。更新用于将现有实体附加到会话。如果您从会话中获取实体,则该实体已附加到该会话,因此更新没有意义

在这种情况下,SaveOrUpdate与Update并不重要——这是一样的

NHibernate跟踪会话中对象的更改。当您提交事务或刷新会话时,它将检查是否有任何更改(存在),然后将这些更改提交到数据库。这一点的关键在于,跟踪哪些对象被更改(脏)不是您的工作,而是NHibernates

其他ORM可能要求您自己跟踪更改,并对任何要持久化的更改对象显式调用某种更新,但NH不能这样工作

因此,为了回答您的问题,如果验证失败,您不想提交事务

using (ITransaction tx = session.BeginTransaction())
{
    // get your object
    // do your validation

    // if you pass validation:
    tx.Commit();

    // if not, roll it back
    tx.Rollback();
}

NH对工作单元模式也持固执己见。因此,如果您在程序的不同逻辑部分执行提交,而您的业务逻辑正在验证工作,则可能会产生摩擦。

我刚刚遇到了同样的问题。Eyston的回答非常有帮助,解释说无论您是否调用iseSession.Update(对象)或SaveOrUpdate(对象),NH都会跟踪更改,提交事务将提交更改

有几种方法可以完成验证,以防止更改进入数据库。在单独的事务中执行所有验证和(可能的)保存

using (ITransaction tx = session.BeginTransaction())
{
    // get your object
    // do your validation

    // if you pass validation:
    tx.Commit();

    // if not, roll it back
    tx.Rollback();
}
我解决问题的方式有点不同。如果验证失败,我不希望对该特定对象进行任何更新,因此我只是将其从会话中逐出

if (!myObj.ValidateForSave())
{
    session.Evict(myObj);
}

通过这种方式,您可以坚持您的单个事务,从页面的开头开始,然后在最后提交。如果您的对象未通过验证,它将不在会话中,并且不会将任何更改保留到数据库中。

在这种情况下,适用于我的解决方案是:

  • 将会话刷新模式设置为“提交”

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

  • “保存”时,每个会话仅打开1个事务,然后放弃该会话


  • 您正在使用NHibernate验证框架吗?如果验证失败,您应该回滚事务,而不是提交它。如果您逐出单个对象,您对会话中其他对象所做的更改仍将提交,这与作为原子操作的事务的粒度背道而驰-它应该是“全部或无”。