DbContext の操作

Entity Framework を使用して .NET オブジェクトを使用してデータのクエリ、挿入、更新、削除を行うには、まず 、モデル で定義されているエンティティとリレーションシップをデータベース内のテーブルにマップするモデルを作成する必要があります。

モデルを作成すると、アプリケーションが対話するプライマリ クラスが System.Data.Entity.DbContext されます (多くの場合、コンテキスト クラスと呼ばれます)。 モデルに関連付けられている DbContext を使用すると、次のことができます。

  • クエリの書き込みと実行
  • クエリ結果をエンティティ オブジェクトとして具体化する
  • これらのオブジェクトに加えられた変更を追跡する
  • オブジェクトの変更をデータベースに保持する
  • メモリ内のオブジェクトを UI コントロールにバインドする

このページでは、コンテキスト クラスを管理する方法に関するいくつかのガイダンスを提供します。

DbContext 派生クラスの定義

コンテキストを操作する推奨される方法は、DbContext から派生し、コンテキスト内の指定されたエンティティのコレクションを表す DbSet プロパティを公開するクラスを定義することです。 EF デザイナーを使用している場合は、コンテキストが自動的に生成されます。 Code First を使用している場合は、通常、コンテキストを自分で記述します。

public class ProductContext : DbContext
{
    public DbSet<Category> Categories { get; set; }
    public DbSet<Product> Products { get; set; }
}

コンテキストを取得したら、これらのプロパティを使用して、コンテキスト内のエンティティのクエリ、追加 ( Add または Attach メソッドの使用) または削除 ( Removeを使用) します。 コンテキスト オブジェクトで DbSet プロパティにアクセスすることは、指定した型のすべてのエンティティを返す開始クエリを表します。 プロパティにアクセスするだけではクエリは実行されないことに注意してください。 クエリは、次の場合に実行されます。

  • これは、 foreach (C#) または For Each (Visual Basic) ステートメントによって列挙されます。
  • ToArrayToDictionaryToListなどのコレクション操作によって列挙されます。
  • FirstAnyなどの LINQ 演算子は、クエリの最も外側の部分で指定されます。
  • 指定したキーを持つエンティティがコンテキストにまだ読み込まれていない場合は、 Load 拡張メソッド、 DbEntityEntry.ReloadDatabase.ExecuteSqlCommand、および DbSet<T>.Findのいずれかのメソッドが呼び出されます。

有効期間

コンテキストの有効期間は、インスタンスの作成時に開始され、インスタンスが破棄されるかガベージ コレクションされたときに終了します。 コンテキストが制御するすべてのリソースをブロックの末尾に破棄する場合は、 using を使用します。 using を使用すると、コンパイラによって try/finally ブロックが自動的に作成され、finally ブロックで dispose が呼び出されます。

public void UseProducts()
{
    using (var context = new ProductContext())
    {     
        // Perform data access using the context
    }
}

コンテキストの有効期間を決定する際の一般的なガイドラインを次に示します。

  • Web アプリケーションを使用する場合は、要求ごとにコンテキスト インスタンスを使用します。
  • Windows Presentation Foundation (WPF) または Windows フォームを使用する場合は、フォームごとにコンテキスト インスタンスを使用します。 これにより、コンテキストによって提供される変更追跡機能を使用できます。
  • 依存関係挿入コンテナーによってコンテキスト インスタンスが作成される場合、通常はコンテナーがコンテキストを破棄する必要があります。
  • コンテキストがアプリケーション コードで作成される場合は、不要になったときにコンテキストを破棄することを忘れないでください。
  • 実行時間の長いコンテキストを使用する場合は、次の点を考慮してください。
    • より多くのオブジェクトとその参照をメモリに読み込むにつれて、コンテキストのメモリ消費量が急速に増加する可能性があります。 これにより、パフォーマンスの問題が発生する可能性があります。
    • コンテキストはスレッド セーフではないため、複数のスレッド間で同時に作業を行う場合は共有しないでください。
    • 例外によってコンテキストが回復不能な状態になると、アプリケーション全体が終了する可能性があります。
    • コンカレンシー関連の問題が発生する可能性は、データのクエリと更新の時間の差が大きくなるにつれて増加します。

接続

既定では、コンテキストによってデータベースへの接続が管理されます。 コンテキストは、必要に応じて接続を開いて閉じます。 たとえば、コンテキストは、クエリを実行する接続を開き、すべての結果セットが処理されたときに接続を閉じます。

接続を開いて閉じるタイミングをより細かく制御したい場合があります。 たとえば、SQL Server Compact を使用する場合、パフォーマンスを向上させるために、アプリケーションの有効期間中はデータベースへの個別のオープン接続を維持することをお勧めします。 このプロセスは、 Connection プロパティを使用して手動で管理できます。