1

リポジトリパターンを使用してASP.NETアプリケーションを開発する場合、各メソッドは、各メソッドのusingブロックを使用して新しいエンティティコンテナーインスタンス(コンテキスト)を作成しますか、またはコンテナーのクラスレベル/プライベートインスタンスを作成しますか?リポジトリ自体が破棄されるまで、いずれかのリポジトリメソッドで使用しますか?以下に記載する以外に、長所と短所は何ですか?私が見ていなかったこれらのそれぞれの利点を組み合わせる方法はありますか?リポジトリはIDisposableを実装しており、リポジトリのインスタンスにブロックを使用して作成できますか?

複数のコンテナ(対単一)

利点:

  • 接続が自動で閉じられる/破棄されるのを防ぎます(usingブロックの最後で閉じられます)。
  • 特定のビュー/ビューモデルに必要なものだけをメモリにプルするように強制し、ラウンドトリップを減らします(遅延ロードしようとすると接続エラーが発生します)。

短所:

  • Controller / View内の子エンティティへのアクセスは、Include()で呼び出したものに制限されます
  • 多くのテーブル(多くの異なるリポジトリメソッド呼び出し)から収集された情報を表示するダッシュボードインデックスのようなページの場合、多くのエンティティコンテナを作成および破棄するオーバーヘッドが追加されます。
4

3 に答える 3

2

リポジトリでコンテキストをインスタンス化する場合は、常にローカルで実行し、using ステートメントでラップする必要があります。

依存性注入を使用してコンテキストを注入している場合は、リクエストが完了したときに、DI コンテナーがコンテキストでの呼び出しを処理するようにします。

ガベージ コレクションが発生するまでコンテキスト リソースが破棄されないため、コンテキストをクラス メンバーとして直接インスタンス化しないでください。その場合は、IDipsosable を実装してコンテキストを破棄し、リポジトリを使用しているものすべてがリポジトリを適切に破棄するようにする必要があります。

于 2012-04-18T18:03:19.113 に答える
0

私は次の 4 点すべてに同意しません。

接続が自動的に閉じられたり破棄されたりするのを防ぎます (using ブロックの最後で閉じられます)。

私の意見では、メソッド レベル、リポジトリ インスタンス レベル、またはリクエスト レベルでコンテキストを破棄するかどうかは問題ではありません。(もちろん、単一のリクエストの最後にコンテキストを破棄する必要があります-リポジトリメソッドをステートメントでラップするか、using提案したように)リポジトリクラスに実装し、コントローラーアクションIDisposableのステートメントでリポジトリインスタンスをラップしますusingまたは、コントローラーコンストラクターでリポジトリをインスタンス化し、それをDisposeコントローラ クラスのオーバーライド - または、リクエストの開始時にコンテキストをインスタンス化し、リクエストの終了時に破棄することによって (一部の依存性注入コンテナーは、この作業を行うのに役立ちます)。コンテキストを「自動破棄」する必要があるのはなぜですか? デスクトップアプリケーションでは、ウィンドウ/ビューごとに何時間も開いている可能性のあるコンテキストを持つことが可能であり、一般的です。

特定のビュー/ビューモデルに必要なものだけを強制的にメモリに取り込むのに役立ち、ラウンドトリップを減らします (遅延読み込みを試みると接続エラーが発生します)。

正直なところ、遅延読み込みを完全に無効にすることでこれを強制します。とにかく、クライアントがサーバーから切断されているWebアプリケーションでは、遅延読み込みの利点は見られません。コントローラーのアクションでは、何をロードする必要があるかを常に把握しており、積極的または明示的なロードを使用できます。EF はクライアントの Web ページの変更を追跡できないため、メモリのオーバーヘッドを回避してパフォーマンスを向上させるために、GET 要求の変更追跡をいつでも無効にすることができます。

コントローラー/ビュー内の子エンティティへのアクセスは、Include() で呼び出したものに限定されます

遅延読み込みの望ましくない驚きがないため、これは欠点というよりむしろ利点です。後でコントローラ アクションで子エンティティを設定する必要がある場合、いくつかの条件に応じてLoadNavigationProperty、同じコンテキストまたは新しいコンテキストを持つ追加のリポジトリ メソッド (または何か) を介してそれらをロードできます。

多くのテーブル (多くの異なるリポジトリ メソッド呼び出し) から収集された情報を表示するダッシュボード インデックスのようなページの場合、多くのエンティティ コンテナーを作成および破棄するオーバーヘッドが追加されます。

コンテキストの作成 (数百または数千のインスタンスについて話しているとは思いません) は安価な操作です。これは非常に理論的なオーバーヘッドであり、実際には役割を果たしません。

Webアプリケーションで言及した両方のアプローチと、3番目のオプション、つまりリクエストごとに単一のコンテキストを作成し、コントローラーアクションで必要なすべてのリポジトリ/サービスにこの同じコンテキストを挿入する方法を使用しました。それらはすべて私のために働きました。

もちろん、複数のコンテキストを使用する場合は、よく知られている例外につながる複数のコンテキストにエンティティを関連付けないように、同じ作業単位ですべての作業を行うように注意する必要があります。通常、この状況を回避することは問題ではありませんが、特に POST 要求を処理する場合は、もう少し注意が必要です。

私は最近、リクエストごとにコンテキストを使用しています。これは、より簡単であり、非常に狭いコンテキストを持つことの利点がわかりません。また、リクエスト処理全体に複数の単一の作業単位を使用する理由がわかりません。何らかの理由で複数のコンテキストが必要な場合は、リクエストの「デフォルトコンテキスト」ではなく、独自のコンテキストで動作する特殊なメソッドをいつでも作成できます。

于 2012-04-18T17:46:15.660 に答える
0

私は個人的に、自分のコンテキストをリポジトリのクラス レベルに置きます。そうする主な理由は、リポジトリ パターンの明確な利点は、リポジトリを簡単に交換して、別のバックエンドを利用できることです。覚えておいてください - リポジトリ パターンの目的は、クライアントにバック データを提供するインターフェイスを提供することです。データ ソースを切り替えたり、(依存性注入を介して) その場で新しいデータ ソースを提供したい場合、メソッドごとのレベルでこれを行うと、はるかに困難な問題が発生します。

Microsoft の MSDN サイトには、リポジトリ パターンに関する適切な情報があります。うまくいけば、これはいくつかのことを明確にするのに役立ちます.

于 2012-04-18T17:30:28.137 に答える