web-dev-qa-db-ja.com

Entity Frameworkとcontext.dispose()の呼び出し

エンティティフレームワークでDbContext.dispose()をいつ呼び出す必要がありますか?

  1. この想像上の方法は悪いですか?

    public static string GetName(string userId)
    {
        var context = new DomainDbContext();
        var userName = context.UserNameItems.FirstOrDefault(x => x.UserId == userId);
        context.Dispose();
        return userName;
    }
    
  2. これは良いですか?

    public static string GetName(string userId)
    {
        string userName;
        using(var context = new DomainDbContext()) {
            userName = context.UserNameItems.FirstOrDefault(x => x.UserId == userId);
            context.Dispose();
        }
        return userName;
    }
    
  3. これはさらに優れています、つまり、using()?を使用するときにcontext.Dispose()を呼び出さないでください

    public static string GetName(string userId)
    {
        string userName;
        using(var context = new DomainDbContext()) {
            userName = context.UserNameItems.FirstOrDefault(x => x.UserId == userId);
        }
        return userName;
    }
    
60
Sindre

実際、これは1つの2つの質問です。

  1. コンテキストのDispose()はいつですか?
  2. 私の文脈の寿命はどうあるべきですか?

回答:

  1. Never 1usingは、_try-finally_ブロック内の暗黙的なDispose()です。例外が以前に発生すると、別のDisposeステートメントが欠落する場合があります。また、ほとんどの場合、Disposeをまったく(暗黙的または明示的に)呼び出しません 有害ではありません

  2. 例参照 Entity Framework 4-winformアプリケーションのコンテキストのライフスパン/スコープ 。要するに、寿命は「短い」べきであり、静的コンテキストは悪いです。


1 一部の人々がコメントしたように、このルールの例外は、コンテキストがIDisposable自体を実装し、そのライフサイクルを共有するコンポーネントの一部である場合です。その場合、コンポーネントのDisposeメソッドでcontext.Dispose()を呼び出します。

95
Gert Arnold

EFを使用するためのいくつかの優れたチュートリアルに従いましたが、コンテキストを破棄しません。

私はそのことに少し興味があり、尊敬されているMicrosoft VIPでさえ、コンテキストを破棄しないことに気付きました。通常の状況ではdbContextを破棄する必要はありませんが見つかりました。

さらに情報が必要な場合は、 このブログ投稿 を読んで、その理由を要約してください。

36
Daniel

さらに良い:

public static string GetName(string userId)
{
    using (var context = new DomainDbContext()) {
        return context.UserNameItems.FirstOrDefault(x => x.UserId == userId);
    }
}

usingスコープ外から結果を返す必要はありません。すぐにそれを返すだけで、目的の廃棄動作が得られます。

13
Todd Menier

データベースコンテキストをクラスフィールドとして定義し、IDisposableを実装できます。以下のようなもの:

public class MyCoolDBManager : IDisposable
{
    // Define the context here.
    private DomainDbContext _db;

    // Constructor.
    public MyCoolDBManager()
    {
        // Create a new instance of the context.
        _db = new DomainDbContext();
    }

    // Your method.
    public string GetName(string userId)
    {           
        string userName = _db.UserNameItems.FirstOrDefault(x => x.UserId == userId);

        return userName;
    } 

    // Implement dispose method.
    // NOTE: It is better to follow the Dispose pattern.
    public void Dispose()
    {
         _db.dispose();
         _db = null;
    }
}
3
A-Sharabiani