将断开连接的对象附加到NHibernate会话; 最佳实践?

我的存储库在UnitOfWork模型中工作; 所有操作,无论是检索还是持久性,都必须在IDisposable UnitOfWork令牌对象的范围内执行,后者在后台与执行所请求工作的Session相关联。 所以,基本模式是:

 using (var uow = repo.BeginUnitOfWork()) { try { //DB operations here; all repo methods require passing in uow. ... repo.CommitUnitOfWork(uow); } catch(Exception) { repo.RollbackUnitOfWork(uow); throw; } } 

我还实现了一些包装器方法,允许您指定将在此框架中执行的lambda或委托,从而减少每次都要实现所有这些脚手架的需要。

我遇到的问题是使用这个模型,代码必须“知道”用户需要什么,并在UnitOfWork使用NHUtil.Initialize()急切加载它。 一旦UOW被置于使用块的末尾,与任何PersistentBags相关联的Session就会被关闭,因此无法对它们进行评估。 由于急切加载所有事情并不总是可行的,并且有点破坏了延迟加载ORM的目的,我正在实现一个Attach()方法。

这是问题; 在没有内置的ISession.Attach()方法的情况下,我看到有三种方法建议将对象与新的Session相关联。 完成这项工作的最佳做​​法是哪一项?

A:

 if(!Session.Contains(domainObject)) Session.Update(domainObject); 

B:

 Session.Merge(domainObject); 

C:

 Session.Lock(domainObject, LockMode.None); 

D:以上都不是。 通过保持你的UOW太短而无法实现延迟加载ORM的目的,有效地禁用延迟加载。 事实上,您必须将断开连接的对象重新关联为正常操作,这意味着您的工作单元边界是错误的。

合并,更新和锁定都有不同的用途。 如果您坚持使用当前的架构,那么Lock可能就是您想要的。

  • 更新 – 关联已更改的对象
  • 锁定 – 关联未更改的对象
  • 合并 – 如果对象存在于当前会话中,则使用合并对象的更改进行更新,否则它与Lock相同