简体   繁体   English

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

[英]Attaching a disconnected object to an NHibernate session; best practice?

My repository works in a UnitOfWork model; 我的存储库在UnitOfWork模型中工作; all operations, whether retrieval or persistence, must be performed within the scope of an IDisposable UnitOfWork token object, which behind the scenes is associated with a Session that performs the work requested. 所有操作,无论是检索还是持久性,都必须在IDisposable UnitOfWork令牌对象的范围内执行,后者在后台与执行所请求工作的Session相关联。 So, the basic pattern is: 所以,基本模式是:

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;
   }
}

I've also implemented some wrapper methods that allow you to specify a lambda or delegate that will be executed in this framework, relieving the need to implement all this scaffolding every time. 我还实现了一些包装器方法,允许您指定将在此框架中执行的lambda或委托,从而减少了每次都实现所有脚手架的需要。

The problem I'm having is that using this model, code must "know" what the user needs, and eager-load it using NHUtil.Initialize() within the UnitOfWork . 我遇到的问题是使用这个模型,代码必须“知道”用户需要什么,并在UnitOfWork使用NHUtil.Initialize()急切加载它。 Once the UOW is disposed at the end of the using block, the Session associated with any PersistentBags is closed, and so they cannot be evaluated. 一旦UOW被置于使用块的末尾,与任何PersistentBags相关联的Session就会被关闭,因此无法对它们进行评估。 As eager-loading everything up front is not always feasible and kind of defeats the purpose of a lazy-loading ORM, I am implementing an Attach() method. 由于急切加载所有事情并不总是可行的,并且有点破坏了延迟加载ORM的目的,我正在实现一个Attach()方法。

Here's the question; 这是问题; In the absence of a built-in ISession.Attach() method, there are three methods I've seen recommended to associate an object with a new Session. 在没有内置的ISession.Attach()方法的情况下,我看到有三种方法建议将对象与新的Session相关联。 Which of them is the best practice to get the job done? 完成工作的最佳做​​法是哪一项?

A: A:

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

B: B:

Session.Merge(domainObject);

C: C:

Session.Lock(domainObject, LockMode.None);

D: None of the above. D:以上都不是。 Effectively disabling lazy-loading by keeping your UOW too short and defeats the purpose of a lazy-loading ORM. 通过保持你的UOW太短而有效地禁用延迟加载并且无法实现延迟加载ORM的目的。 The fact that you have to re-associate disconnected objects as normal operations means that your unit of work boundaries are wrong. 您必须将断开连接的对象重新关联为正常操作,这意味着您的工作单元边界是错误的。

Merge, Update, and Lock all have different purposes. 合并,更新和锁定都有不同的用途。 If you're stuck with your current architecture then Lock is probably what you want. 如果您坚持使用当前的架构,那么Lock可能就是您想要的。

  • Update - associates a changed object 更新 - 关联已更改的对象
  • Lock - associates an unchanged object 锁定 - 关联未更改的对象
  • Merge - if the object exists in the current session then it is updated with changes from the merged object, otherwise it's the same as Lock 合并 - 如果对象存在于当前会话中,则使用合并对象的更改进行更新,否则它与Lock相同

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM