2017-07-30 5 views
0

EFのdbContextオブジェクトを削除していることを確認します。MVCコントローラでEF DBContextを処理する

現在、静的メソッドを使用して、すべてのデータレイヤーの項目をブラックボックス化してコントローラーから除外するEFクラッシュ操作を呼び出しています。

以下の例では、IQueryableを返す1つのメソッドがあり、クエリが配置済みコンテキストオブジェクトで実行しようとすると例外が発生するUsingステートメントが使用されています。

もう1つはUsingステートメントを使用せず、うまく動作しますが、処分されていますか?

IQueryableではなくIEnumerableを返すだけでよいですか?

public class MyContext : DbContext 
{ 
    public MyContext() : base("MyConnectionString") 
    { 
     Database.SetInitializer<EFContext>(null); 
    } 

    public DbSet<User> Users { get; set; } 
    public DbSet<Role> Roles { get; set; } 
} 


public class Data 
{ 
    // Fails when IQuerable tried to run against a disposed MyContext object 
    public static T Get<T>(params string[] joins) 
    { 
     using (var context = new MyContext()) 
     { 
      return context.Get<T>(joins); 
     } 
    } 

    // Works fine but when is it disposed? 
    public static T Get<T>(params string[] joins) 
    { 
     return new MyContext().Get<T>(joins); 
    } 
} 

public ActionResult GetUser(int id = 0) 
{ 
    var data = Data.Get<User>(); 
    return View("Users", model); 
} 

答えて

4

問題がIQueryableまたはIEnumerableの使用についてではありません。 IQueryableまたはIEnumerableを返すので例外がありますが、LINQは実行されていません。あなたはデータベースへの接続を開いた後、クエリを設定した後に閉じます。

これを解決するために、あなたは ToListToArraySingle[OrDefault]First[OrDefault]等...拡張メソッドを呼び出すことにより、LINQクエリを実行する必要があります。

Webアプリケーションを使用しているため、Webリクエストの全ライフにわたって、DbContextという1つのインスタンスを持つことをお勧めします。 DI(Dependency Injection)を使用することをお勧めします。非常に簡単なDIですSimple Injectorを試すことができます。あなたがしてくださいDIについて学習するので、ちょうどこの手順に従ってDIを使用するが、時間を取ることができない場合は

:):

Web要求が到着
  1. は、にあなたのDbContextの新しいインスタンスを保存しますコレクションHttpContext.Items
  2. あなたの方法では、DbContextHttpContext.Itemsから検索して使用するだけです。
  3. ウェブリクエストが終了している場合は、DbContextを廃棄してください。
+0

私はDIに精通していますが、私は私のOPで述べたように、データアクセスをUIレイヤーから外してブラックボックス化したいと考えています。 APIのように使用するのはほぼ – user3953989

+2

DIです。インターフェース/抽象を再びプログラムするので、あなたがやろうとしているブラックボックス化されたものを含むすべてのソリッドの原則に従います。 – CodeNotFound

+0

この例を追加できますか? – user3953989

関連する問題