ここDbContext
では、派生クラスが実際に少なくとも 3 つのことを管理しています。
- データベースとエンティティ モデルを記述するメタデータ
- 基礎となるデータベース接続、および
- 変更の追跡、関係の修正などのために、コンテキストを使用して読み込まれたエンティティのクライアント側の「キャッシュ」。 EFs 機能. 該当する場合、アプリケーションでの適切なキャッシュの代わりにはなりません)。
Entity Framework は通常、メタデータ (項目 1) をキャッシュして、すべてのコンテキスト インスタンス (または、少なくとも同じ接続文字列を使用するすべてのインスタンス) で共有されるようにします。したがって、ここでは心配する必要はありません。
他のコメントで述べたように、コードは 2 つのデータベース接続を使用することになります。これは、問題になる場合とそうでない場合があります。
また、クライアント キャッシュが 2 つになります (項目 3)。外側のコンテキストからエンティティをロードした場合、再び内側のコンテキストから、メモリ内にエンティティの 2 つのコピーが作成されます。これは間違いなく混乱を招き、微妙なバグにつながる可能性があります。つまり、共有コンテキスト オブジェクトを使用したくない場合は、オプション 2 の方がオプション 1 よりも優れている可能性があります。
transactionsを使用している場合は、さらに考慮事項があります。複数のデータベース接続があると、トランザクションが分散トランザクションに昇格する可能性がありますが、これはおそらく望ましくありません。db トランザクションについて言及していないので、ここではこれ以上説明しません。
それで、これはあなたをどこに残しますか?
このパターンを単にDbContext
コード内でのオブジェクトの受け渡しを避けるために使用している場合は、コンテキストをパラメーターとして受け取るようにリファクタリングする方がよいでしょうMethodB
。寿命の長いコンテキスト オブジェクトをどのようにすべきかという問題は、繰り返し出てきます。経験則として、単一のデータベース操作または関連する一連のデータベース操作に対して新しいコンテキストを作成します。(たとえば、このブログ投稿とこの質問を参照してください。)
DbContext
(別の方法として、既存の接続を受け取る派生クラスにコンストラクターを追加することもできます。その後、複数のコンテキスト間で同じ接続を共有できます。)
便利なパターンの 1 つは、コンテキスト オブジェクトを作成し、それをプライベート フィールドまたはプロパティとして格納する独自のクラスを作成することです。次に、クラスを実装IDisposable
し、そのDispose()
メソッドがコンテキスト オブジェクトを破棄します。呼び出しコードは、クラスのインスタンスを通知し、コンテキストや接続についてまったく心配する必要はありません。
複数のコンテキストを同時にアクティブにする必要があるのはいつですか?
これは、マルチスレッドのコードを記述する必要がある場合に役立ちます。データベース接続はスレッド セーフではないため、一度に 1 つのスレッドからのみ接続 (したがって EF コンテキスト) にアクセスする必要があります。制限が厳しすぎる場合は、スレッドごとに 1 つずつ、複数の接続 (およびコンテキスト) が必要です。これは面白いと思うかもしれません。