私は次の 4 点すべてに同意しません。
接続が自動的に閉じられたり破棄されたりするのを防ぎます (using ブロックの最後で閉じられます)。
私の意見では、メソッド レベル、リポジトリ インスタンス レベル、またはリクエスト レベルでコンテキストを破棄するかどうかは問題ではありません。(もちろん、単一のリクエストの最後にコンテキストを破棄する必要があります-リポジトリメソッドをステートメントでラップするか、(using
提案したように)リポジトリクラスに実装し、コントローラーアクションIDisposable
のステートメントでリポジトリインスタンスをラップしますusing
または、コントローラーコンストラクターでリポジトリをインスタンス化し、それをDispose
コントローラ クラスのオーバーライド - または、リクエストの開始時にコンテキストをインスタンス化し、リクエストの終了時に破棄することによって (一部の依存性注入コンテナーは、この作業を行うのに役立ちます)。コンテキストを「自動破棄」する必要があるのはなぜですか? デスクトップアプリケーションでは、ウィンドウ/ビューごとに何時間も開いている可能性のあるコンテキストを持つことが可能であり、一般的です。
特定のビュー/ビューモデルに必要なものだけを強制的にメモリに取り込むのに役立ち、ラウンドトリップを減らします (遅延読み込みを試みると接続エラーが発生します)。
正直なところ、遅延読み込みを完全に無効にすることでこれを強制します。とにかく、クライアントがサーバーから切断されているWebアプリケーションでは、遅延読み込みの利点は見られません。コントローラーのアクションでは、何をロードする必要があるかを常に把握しており、積極的または明示的なロードを使用できます。EF はクライアントの Web ページの変更を追跡できないため、メモリのオーバーヘッドを回避してパフォーマンスを向上させるために、GET 要求の変更追跡をいつでも無効にすることができます。
コントローラー/ビュー内の子エンティティへのアクセスは、Include() で呼び出したものに限定されます
遅延読み込みの望ましくない驚きがないため、これは欠点というよりむしろ利点です。後でコントローラ アクションで子エンティティを設定する必要がある場合、いくつかの条件に応じてLoadNavigationProperty
、同じコンテキストまたは新しいコンテキストを持つ追加のリポジトリ メソッド (または何か) を介してそれらをロードできます。
多くのテーブル (多くの異なるリポジトリ メソッド呼び出し) から収集された情報を表示するダッシュボード インデックスのようなページの場合、多くのエンティティ コンテナーを作成および破棄するオーバーヘッドが追加されます。
コンテキストの作成 (数百または数千のインスタンスについて話しているとは思いません) は安価な操作です。これは非常に理論的なオーバーヘッドであり、実際には役割を果たしません。
Webアプリケーションで言及した両方のアプローチと、3番目のオプション、つまりリクエストごとに単一のコンテキストを作成し、コントローラーアクションで必要なすべてのリポジトリ/サービスにこの同じコンテキストを挿入する方法を使用しました。それらはすべて私のために働きました。
もちろん、複数のコンテキストを使用する場合は、よく知られている例外につながる複数のコンテキストにエンティティを関連付けないように、同じ作業単位ですべての作業を行うように注意する必要があります。通常、この状況を回避することは問題ではありませんが、特に POST 要求を処理する場合は、もう少し注意が必要です。
私は最近、リクエストごとにコンテキストを使用しています。これは、より簡単であり、非常に狭いコンテキストを持つことの利点がわかりません。また、リクエスト処理全体に複数の単一の作業単位を使用する理由がわかりません。何らかの理由で複数のコンテキストが必要な場合は、リクエストの「デフォルトコンテキスト」ではなく、独自のコンテキストで動作する特殊なメソッドをいつでも作成できます。