エンティティフレームワークでDbContext.dispose()
をいつ呼び出す必要がありますか?
この想像上の方法は悪いですか?
public static string GetName(string userId)
{
var context = new DomainDbContext();
var userName = context.UserNameItems.FirstOrDefault(x => x.UserId == userId);
context.Dispose();
return userName;
}
これは良いですか?
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;
}
これはさらに優れています、つまり、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;
}
実際、これは1つの2つの質問です。
Dispose()
はいつですか?回答:
Never 1。 using
は、_try-finally
_ブロック内の暗黙的なDispose()
です。例外が以前に発生すると、別のDispose
ステートメントが欠落する場合があります。また、ほとんどの場合、Dispose
をまったく(暗黙的または明示的に)呼び出しません 有害ではありません 。
例参照 Entity Framework 4-winformアプリケーションのコンテキストのライフスパン/スコープ 。要するに、寿命は「短い」べきであり、静的コンテキストは悪いです。
1 一部の人々がコメントしたように、このルールの例外は、コンテキストがIDisposable
自体を実装し、そのライフサイクルを共有するコンポーネントの一部である場合です。その場合、コンポーネントのDispose
メソッドでcontext.Dispose()
を呼び出します。
EFを使用するためのいくつかの優れたチュートリアルに従いましたが、コンテキストを破棄しません。
私はそのことに少し興味があり、尊敬されているMicrosoft VIPでさえ、コンテキストを破棄しないことに気付きました。通常の状況ではdbContextを破棄する必要はありませんが見つかりました。
さらに情報が必要な場合は、 このブログ投稿 を読んで、その理由を要約してください。
さらに良い:
public static string GetName(string userId)
{
using (var context = new DomainDbContext()) {
return context.UserNameItems.FirstOrDefault(x => x.UserId == userId);
}
}
using
スコープ外から結果を返す必要はありません。すぐにそれを返すだけで、目的の廃棄動作が得られます。
データベースコンテキストをクラスフィールドとして定義し、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;
}
}