如何使用NHibernate插入一个已经存在于数据库中的分离对象?

时间:2009-11-19 07:46:41

标签: .net nhibernate

我有以下代码段:

using (var scope = DataAccessPortal.DataContext(DB.Main).OpenStatementScope())
using (var transaction = scope.BeginTransaction())
{
  // Several other database operations.
  if (scope.ExistsById(obj.GetType(), obj.Id))
  {
    scope.Update(obj);
  }
  else
  {
    scope.Insert(obj);
  }
  transaction.Commit();
}

scopetransaction分别是NHibernate会话和事务对象周围的精简抽象层,ExistsById映射到HQL查询以检查是否在数据库中找到了给定的ID,{ {1}}和Update映射到相应的会话操作。

代码的目的是更新数据库中的多个对象,然后更新数据库中的某些对象,这些对象可能已经或可能没有在那里找到 - 更新或插入代码。

我不喜欢更新或插入代码,因为它产生了两次到数据库的往返。是否可以使用NHibernate进行一次往返完成相同的任务?

我的约束是:

  • 数据库没有预定义的存储过程。如果NHibernate允许以DB独立的方式动态创建一个,那么很好(如何???),否则使用存储过程不是一个选项。
  • 有可能对象已经存在于数据库中,因此我可以执行Update,如果对象不存在则捕获异常,然后使用Insert重试。但是,更新或插入代码是更大事务的一部分。因此,如果失败也会使事务失败,这意味着我将不得不重试整个事务,而不仅仅是更新或插入代码。我不确定它比现在的方式更可取。

1 个答案:

答案 0 :(得分:1)

在任何情况下都需要DB往返。 NHibernate会话充当客户端缓存,使业务对象和数据库保持同步。因此,如果您分离然后重新附加对象,则会话除了针对该对象重新检查数据库之外别无他法。没有其他办法,如果你想一下......

通常,这是通过像这样的会话Refresh()方法(伪代码)完成的:

ISession session = GetSession(); 
session.Refresh(obj); 
session.DoSomething();

无论你是否有某种外观或包装都没关系。整体模式保持不变:您必须先检查数据库,然后才能做某事......