web-dev-qa-db-ja.com

MVCでDbContextをインスタンス化して破棄するための最良の方法は何ですか?

MVC 3 + EF 4.1

DbContextを処理するために2つのアプローチから選択しています。

  1. _Application_BeginRequest_でインスタンス化し、_HttpContext.Current.Items_に入れ、_Application_EndRequest_で破棄します。
  2. 使い捨てのUnitOfWork(DbContextの一種のラッパー)を作成し、using(var unitOfWork = new UnitOfWork()) { ... }で各コントローラーアクションを開始します

あなたの経験を共有してください:あなたはどちらを好みますか?各アプローチの長所と短所は何ですか?

30
YMC

依存性注入フレームワークを使用することをお勧めします。リクエストに応じてDbContextを登録できます

 container.RegisterType<MyDbContext>().InstancePerHttpRequest();

そして、それをコンストラクターパラメーターとしてコントローラーに挿入します。

public class MyController : Controller
{
    public MyController(MyDbContext myDbContext)
    {
         _myDbContext = myDbContext;
    }
}

登録されたタイプがIDisposableを実装している場合、DIフレームワークはリクエストの終了時にそれを破棄します。

1番目のアプローチ:IDフレームワークを手動で実装するよりも、使用する方がはるかにクリーンです。さらに、すべてのリクエストにUoWが必要ない場合があります。

2番目のアプローチ:コントローラーは、UoW(DbContext)を構築する方法を知らないはずです。目的は、コンポーネント間の結合を減らすことではありません。

18
Eranga

現在、リポジトリファクトリからサービスロケータを介してインスタンス化されたUoW(作業単位)が注入されたリポジトリを使用しています。 Unityはこのようにライフタイムを制御し、作業をあなたから遠ざけます。

特定の実装は、POCO、エンティティオブジェクトなどを使用しているかどうかによって異なります。

最終的には、コントローラーで複数のオブジェクトセットを操作して、1つのコンテキストのみを使用するようにする場合は、UoWが必要です。これにより、取引が抑制されます。

複数のオブジェクトコンテキスト(つまり、複数のEDMX)を使用する場合は、MSDTCでUoWを使用することを検討する必要があります...しかし、それはおそらくあなたが知りたい以上のものです。結局のところ、重要なことは、コントローラーアクションに必要なもの(つまり、コンテキストの1つのインスタンス)をインスタンス化することです。 Begin_Requestを使用するとは思わないので、すべてのリクエストにコンテキストが必要なわけではありません。

2
Chris Yeaste