.AsNoTracking()
拡張機能に関して質問があります。これはまったく新しいものであり、非常に紛らわしいものです。
私はウェブサイトにリクエストごとのコンテキストを使用しています。
多くのエンティティは変更されないため、追跡する必要はありませんが、データベースに何が起こっているのか、この場合に違いが生じるかどうかがわからない次のシナリオがあります。
この例は私が現在していることです:
context.Set<User>().AsNoTracking()
// Step 1) Get user
context.Set<User>()
// Step 2) Update user
これは上記と同じですが、ステップ1から.AsNoTracking()
を削除します。
context.Set<User>();
// Step 1) Get user
context.Set<User>()
// Step 2) Update user
ステップ1と2は同じコンテキストを使用しますが、異なるタイミングで発生します。私が解決できないのは、違いがあるかどうかです。ステップ2は更新であるため、両方ともデータベースに2回ヒットすると推測しています。
違いは何ですか?
違いは、最初のケースでは取得されたユーザーはコンテキストによって追跡されないため、ユーザーをデータベースに保存するときに、それを添付してユーザーの状態を正しく設定し、EFが既存のユーザーを更新する必要があることを知る必要があることです新しいものを挿入する代わりに。 2番目のケースでは、同じコンテキストインスタンスでユーザーを読み込んで保存する場合、追跡メカニズムが自動的に処理するため、これを行う必要はありません。
このページをご覧ください Entity Framework and AsNoTracking
Entity Frameworkは、アプリケーションのパフォーマンスを最適化するのに役立つ多くのパフォーマンスチューニングオプションを公開しています。これらのチューニングオプションの1つは.AsNoTracking()
です。この最適化により、Entity Framework
にクエリの結果を追跡しないように指示できます。これは、Entity Framework
がクエリによって返されるエンティティの追加の処理またはストレージを実行しないことを意味します。ただし、これらのエンティティは、追跡グラフに再アタッチせずに更新できないことも意味します。
AsNoTrackingを使用することにより、パフォーマンスが大幅に向上します
トラッキングLINQ to Entitiesクエリなし
クエリが読み取り操作用である場合は、AsNoTracking()の使用をお勧めします。これらのシナリオでは、エンティティを取得しますが、コンテキストによって追跡されません。これにより、最小限のメモリ使用量と最適なパフォーマンスが保証されます。
長所
- 通常のLINQクエリよりもパフォーマンスが向上しました。
- 完全に実体化されたオブジェクト。
- プログラミング言語に組み込まれた構文で記述するのが最も簡単です。
短所
- CUD操作には適していません。
- 以下のような特定の技術的制限:OUTER JOINクエリにDefaultIfEmptyを使用するパターンは、Entity SQLの単純なOUTER JOINステートメントよりも複雑なクエリになります。
- 通常のパターンマッチングではLIKEを使用できません。
ここで利用可能な詳細情報:
追跡を無効にすると、結果セットがメモリにストリーミングされます。これは、大量のデータセットを使用していて、データセット全体を一度に必要としない場合に効率的です。
参照:
AsNoTracking()を使用すると、EFの「レコードごとの一意のキー」要件をバイパスできます(他の回答では明示的に言及されていません)。
これは、一部のフィールドがNULL入力可能であるか、ビューの性質が論理的にインデックス化できないため、一意のキーをサポートしないビューを読み取るときに非常に役立ちます。
これらの場合、「キー」はNULL不可列に設定できますが、AsNoTracking()はすべてのクエリで使用する必要があります。そうでない場合、レコード(キーによる複製)はスキップされます。
DBを変更する他の何か(別のプロセスなど)があり、これらの変更を確認する必要がある場合は、AsNoTracking()
を使用します。クエリ:
http://codethug.com/2016/02/19/Entity-Framework-Cache-Busting/