2012-03-19 8 views
0

EFで遅延読み込み機能をサポートするには、DbContextをインスタンス化する最良の方法は何ですか?ASP.NET MVCのEF DbContextインスタンスを作成する最適な方法は何ですか

私はHttpContextの現在の項目がApplication_BeginRequest方法とApplication_EndRequestメソッドを介してDbContextを作成するには良い場所ですけど、MSDNおよび公式asp.net MVCサイトのいくつかのサンプルコードでは、彼らは単にコントローラのコンストラクタでDbContextを作成し、それを処分しますコントローラのDispose()メソッド。

私は、両方の方法がすべてリクエストパターンごとにセッションを実装するので、あまりにも違いないと思います。

私の理解が正しいかどうかを確認したいだけです。

答えて

1

コントローラ内のDispose()メソッドは、必ずしも信頼できるとは限りません。同様に、セッションもおそらく良いアイデアではありません。 「Best」はおそらく主観的ですが、Dependency Injection(Castle Windsor)を使用し、Unit Unit of Work Repositoryのパターンに従うことで最も成功しました。

セットアップ次の行に沿って作業単位:

public class UnitOfWork : IUnitOfWork 
{ 
    public UnitOfWork() 
    { 
     this.Context = new MyEFEntities(); 
     this.Context.ContextOptions.LazyLoadingEnabled = true; 
    } 

    public void Dispose() 
    { 
     this.Context.Dispose(); 
    } 

    public ObjectContext Context { get; internal set; } 
} 

セットアップリポジトリ:Global.asaxの城と

public class Repository<TEntity> : IRepository<TEntity> 
    where TEntity : class 
{ 
    public Repository(IUnitOfWork unitOfWork) 
    { 
     Context = unitOfWork.Context; 
     ObjectSet = Context.CreateObjectSet<TEntity>(); 
    } 
    public ObjectContext Context { get; set; } 
    public IObjectSet<TEntity> ObjectSet { get; set; } 
} 

登録:

void Application_Start() 
{ 
    this.Container.Register(
     Component.For<IUnitOfWork>() 
      .UsingFactoryMethod(() => new UnitOfWork()) 
      .LifeStyle 
      .Is(LifestyleType.PerWebRequest) 
     ); 

    ControllerBuilder.Current.SetControllerFactory(
     new WindsorControllerFactory(this.Container)); 
} 

とで使用あなたのコントローラー(または使用している限り、注射可能な限り):

public class SomeController 
{ 
    public SomeController(IRepository<MyEntity> repository) 
    { 
     this.Repository = repository; 
    } 

    public IRepository<MyEntity> Repository { get; set; } 

    public ActionResult MyAction() 
    { 
     ViewData.Model = this.Repository.ObjectSet.Single(x => x.Condition); //or something... 
    } 
} 
+0

あなたの返信lukifferに感謝しますが、私の質問はDIのものではなく、リポジトリではなく、より基本的なものに焦点を当てています。私は、リポジトリとDIコンテナを使用せずにbegin/endrequestイベントまたはコントローラクラスの両方でどのアプローチが最善であるか疑問に思っています。 – Ray

+0

開始/終了要求イベントにアタッチすることで、コントローラの中だけでなく(フィルタなど)、要求の全期間を通じてデータインターフェイスの同じインスタンスにアクセスできますが、最終的には同じです。私が長い説明をする唯一の理由は、ウェブファーム/ウェブガーデンのリクエストコンテキストで問題を追跡することに問題があったためです。これが最終的にはうまくいきました。 – lukiffer

+0

遅延ロードをサポートするには両方の方法が理にかなっていますか? – Ray

1

ここでの遅延読み込みは、将来の問題のトラップになる可能性があります。 DIがなければ、リポジトリがなくても、怠惰な読み込みのためにハックされることなく何かを見るのは難しいです。エンティティをビューに渡すことも計画しています。もしそうなら、これは悪いオーバーラップを作り出すでしょう。コントローラはビ​​ューのデータをパッケージ化する必要があります。後でビューで評価されるものはありません。

MVCのベストプラクティスでは、可能であればビューモデル(平坦化が意味をなさない場合)にドメインモデルを平坦化し、ビューモデルを使用する必要があります。理想的には、何が遅延ロードされるのかを知ることができるので、ヒットを前面に出し、クエリの.Include()を熱心な負荷に使用する方が理にかなっています。そうしないと、データベースに多数のクエリを発行できます。

0

セッションファクトリパターンを使用し、セッションオブジェクトにDBContextを保存しました。セッションごとに開かれたままです。私はこれまでにそれに問題がなかった。

関連する問題