NHibernate提交db更改,无需显式调用以保存或更新

7 nhibernate

我在ASP.NET中使用Nhibernate 2.0.我在页面的开头启动事务并在最后提交事务.在页面中: - 我得到一个对象 - 我更改了对象属性 - 我验证了对象 - 如果验证正常我在该对象上调用save-update - 如果验证错误,我不会调用save-update on那个对象 - 我总是在页面末尾提交事务.

问题是,当验证错误并且我没有对对象进行任何调用save-update时,提交transactin会提交DB中的更改.

我将FlushMode设置为Never但nothig change.

有建议吗?我错了什么?

ano*_*ous 17

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

如果从会话中获取对象,那么您就会误解更新.更新用于将现有实体附加到会话.如果从会话中获取实体,则它已附加到该会话,因此更新无意义.

在这种情况下SaveOrUpdate与Update无关紧要 - 同样的事情.

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

其他ORM可能要求您自己跟踪更改并在要更改的任何对象上明确调用某种更新,但NH不会以这种方式工作.

所以要回答你的问题,如果验证失败,你不想提交交易.

NH也对工作单元模式持主观态度.因此,如果您在验证工作的业务逻辑中对程序的不同逻辑部分进行提交,则可能会导致摩擦.


Sam*_*ham 5

我刚遇到同样的问题.Eyston的回答非常有用,解释说无论您是否调用ISession.Update(object)或SaveOrUpdate(object),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();
}
Run Code Online (Sandbox Code Playgroud)

我有点不同地解决了我的问题.如果我的验证失败,我不希望对该特定对象进行任何更新,因此我只是将其从会话中逐出.

if (!myObj.ValidateForSave())
{
    session.Evict(myObj);
}
Run Code Online (Sandbox Code Playgroud)

这样做,你可以坚持你的单一交易,在页面的开头开始,并在最后提交它.如果您的对象验证失败,它将不在会话中,并且不会对数据库保留任何更改.

  • 如果验证失败,则应回滚事务,而不是提交事务.如果你驱逐单个对象,你对会话中其他对象所做的更改仍然会被提交,这违背了作为原子操作的事务 - 它应该是"全有或全无". (4认同)