EF で動的プロキシについて話す場合、区別すべき 2 つの異なるタイプがあります。
通常、変更追跡プロキシは、遅延読み込みのプロキシとしても機能します。逆は当てはまりません。これは、変更追跡プロキシの要件が高く、特にすべてのプロパティ (スカラー プロパティも同様) が である必要があるためvirtual
です。遅延読み込みの場合は、ナビゲーション プロパティが で十分ですvirtual
。
変更追跡プロキシが常に遅延読み込みを利用できるという事実が、DbContext にこの構成フラグがある主な理由です。
DbContext.Configuration.LazyLoadingEnabled
このフラグはデフォルトで true です。これを設定するとfalse
、プロキシが作成されていても遅延読み込みが無効になります。これは、変更追跡プロキシを使用しているが、それらのプロキシを遅延読み込みにも使用したくない場合に特に重要です。
オプション ...
DbContext.Configuration.ProxyCreationEnabled
...プロキシの作成を完全に無効にします-変更の追跡と遅延読み込みも同様です。
どちらのフラグも、エンティティ クラスが変更追跡プロキシまたは遅延読み込みプロキシのいずれかを作成するための要件を満たしている場合にのみ意味を持ちます。
これで、動的な遅延読み込みプロキシの目的がわかりました。では、なぜ動的変更追跡プロキシを使用する必要があるのでしょうか?
実際、私が認識している唯一の理由はパフォーマンスです。しかし、これは非常に強力な理由です。スナップショット ベースの変更追跡とプロキシ ベースの変更追跡を比較すると、パフォーマンスの違いは非常に大きいです。私の測定では、50 倍から 100 倍が現実的です (スナップショット ベースの変更追跡で 10000 個のエンティティに対して約 1 時間、30 秒から 60 秒かかる方法から取得)。変更追跡プロキシを有効にするためにすべてのプロパティを仮想化した後)。多くの (たとえば 1000 以上の) エンティティを処理および変更するアプリケーションがある場合、これは重要な要素になります。Web 要求内の単一のエンティティに対して作成/変更/削除操作しかできない Web アプリケーションでは、この違いはそれほど重要ではありません。
ほとんどすべての状況で、遅延読み込みプロキシを使用したくない場合は、熱心な読み込みまたは明示的な読み込みを利用して同じ目標を達成できます。プロキシ ベースの遅延読み込みまたは非プロキシ ベースの明示的な読み込みのパフォーマンスは同じです。これは、ナビゲーション プロパティが読み込まれるときに基本的に同じクエリが発生するためです。最初のケースではプロキシがクエリを実行し、2 番目のケースでは手書きのコードが実行されます。そのため、遅延読み込みプロキシを使用せずに、大きな損失を被ることなく生活できます。
しかし、多くのエンティティを処理するために妥当なパフォーマンスが必要な場合は、変更追跡プロキシに代わるものはありませんEntityObject
-EF 4.0 で派生エンティティを使用する (使用するときに禁止されているため、EF 4.1 ではオプションではありDbContext
ません) か、Entity Framework をまったく使用しないことを除いて.
編集 (2012 年 5 月)
その間、スナップショット ベースの追跡と比較して、変更追跡プロキシが高速ではない、またはパフォーマンスがさらに悪い状況があることを知りました。
変更追跡プロキシを使用する際のこれらの複雑さのため、推奨される方法は、デフォルトでスナップショット ベースの変更追跡を使用し、(いくつかのテストを行った後に) プロキシを慎重に使用することです (いくつかのテストを行った後)。追跡を変更します。