2010-12-14 7 views
14

私のリポジトリはUnitOfWorkモデルで動作します。検索や永続のいずれの操作も、IDisposableUnitOfWorkトークンオブジェクトの範囲内で実行する必要があります。トークンオブジェクトの背後には、要求された作業を実行するSessionが関連付けられています。だから、基本的なパターンは次のとおりです。NHibernateセッションに切断オブジェクトをアタッチする。ベストプラクティス?

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

私も毎回すべて、この足場を実装する必要性を軽減、あなたはこの枠組みの中で実行されるラムダまたはデリゲートを指定することができ、いくつかのラッパー・メソッドを実装しました。

私が抱えている問題は、このモデルを使用すると、コードがUnitOfWork内のNHUtil.Initialize()を使用して、ユーザーが必要としていることを「知って」いることがわかります。 UOWが使用ブロックの最後に配置されると、PersistentBagsに関連付けられたセッションは閉じられ、評価されません。前向きなものをすべて積み重ねることは必ずしも実現可能ではないし、遅延ロードORMの目的を破るようなものであるので、私はAttach()メソッドを実装しています。

ここに質問があります。組み込みのISession.Attach()メソッドがない場合は、オブジェクトを新しいセッションに関連付けることを推奨している3つのメソッドがあります。仕事を終わらせるベストプラクティスはどれですか?

A:

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

B:

Session.Merge(domainObject); 

C:

Session.Lock(domainObject, LockMode.None); 

答えて

24

D:上記のなし。あなたのUOWをあまりにも短く保つことによってレイジーローディングを効果的に無効にし、レイジーローディングORMの目的を無効にします。切断されたオブジェクトを通常の操作として再関連付けする必要があるという事実は、作業単位の境界が間違っていることを意味します。

マージ、更新、ロックはすべて異なる目的を持っています。あなたの現在のアーキテクチャに悩まされているなら、おそらくロックはあなたが望むものです。

  • 更新 - 変更されたオブジェクト
  • ロックを関連付ける -
  • マージをそのままオブジェクトを関連付ける - オブジェクトが 現在のセッションに存在する場合、それは、マージされたオブジェクトからの変更と 、 に更新され、それ以外の場合はですロックと同じです。
+0

十分に公正です。私は現在のレポアーキテクチャに縛られていません。基本的なパターンは、UnitOfWorkオブジェクトがIDisposableを実装するフライウェイトトークンであり、セッションがクリーンアップされるようにリポジトリにコールバックすることです。現在、Dispose()はユーザコードによって呼び出されなければならず、そうでなければDBはオープンのままなので、使用パターンは最も論理的です。 IDisposableの実装をより堅牢にすることができますので、オブジェクトがGCedされているときに必要に応じて呼び出されるか、他のパターンを見ることができます。あなたの提案? – KeithS

+0

実際には、「よりロバストな」パートをキャンセルしてください。リポジトリ内のUOWへの参照があるので、明示的に配置しない限り、リポジトリが破棄されるまで(プログラムの有効期間中はIoCコンテナを介してメモリに保持されます) – KeithS

+0

UOWをリポジトリのコンストラクタに渡す必要があります。個人的に私は、それをラップするのではなく、直接セッションを使用します。セッションを廃棄することは重要ですが、多くの場合、それを使用ブロックにラップするのは実際的ではなく、適切な時期にDisposeを呼び出す必要があります。 –

関連する問題