web-dev-qa-db-ja.com

.AsNoTracking()はどのような違いをもたらしますか?

.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回ヒットすると推測しています。

違いは何ですか?

188
dotnetnoob

違いは、最初のケースでは取得されたユーザーはコンテキストによって追跡されないため、ユーザーをデータベースに保存するときに、それを添付してユーザーの状態を正しく設定し、EFが既存のユーザーを更新する必要があることを知る必要があることです新しいものを挿入する代わりに。 2番目のケースでは、同じコンテキストインスタンスでユーザーを読み込んで保存する場合、追跡メカニズムが自動的に処理するため、これを行う必要はありません。

153
Ladislav Mrnka

このページをご覧ください Entity Framework and AsNoTracking

AsNoTrackingの機能

Entity Frameworkは、アプリケーションのパフォーマンスを最適化するのに役立つ多くのパフォーマンスチューニングオプションを公開しています。これらのチューニングオプションの1つは.AsNoTracking()です。この最適化により、Entity Frameworkにクエリの結果を追跡しないように指示できます。これは、Entity Frameworkがクエリによって返されるエンティティの追加の処理またはストレージを実行しないことを意味します。ただし、これらのエンティティは、追跡グラフに再アタッチせずに更新できないことも意味します。

AsNoTrackingを使用することにより、パフォーマンスが大幅に向上します

140
Moji

トラッキングLINQ to Entitiesクエリなし

クエリが読み取り操作用である場合は、AsNoTracking()の使用をお勧めします。これらのシナリオでは、エンティティを取得しますが、コンテキストによって追跡されません。これにより、最小限のメモリ使用量と最適なパフォーマンスが保証されます。

長所

  1. 通常のLINQクエリよりもパフォーマンスが向上しました。
  2. 完全に実体化されたオブジェクト。
  3. プログラミング言語に組み込まれた構文で記述するのが最も簡単です。

短所

  1. CUD操作には適していません。
  2. 以下のような特定の技術的制限:OUTER JOINクエリにDefaultIfEmptyを使用するパターンは、Entity SQLの単純なOUTER JOINステートメントよりも複雑なクエリになります。
  3. 通常のパターンマッチングではLIKEを使用できません。

ここで利用可能な詳細情報:

Entity Frameworkのパフォーマンスに関する考慮事項

Entity FrameworkとNoTracking

38
NullReference

追跡を無効にすると、結果セットがメモリにストリーミングされます。これは、大量のデータセットを使用していて、データセット全体を一度に必要としない場合に効率的です。

参照:

31
Ronnie Overby

AsNoTracking()を使用すると、EFの「レコードごとの一意のキー」要件をバイパスできます(他の回答では明示的に言及されていません)。

これは、一部のフィールドがNULL入力可能であるか、ビューの性質が論理的にインデックス化できないため、一意のキーをサポートしないビューを読み取るときに非常に役立ちます。

これらの場合、「キー」はNULL不可列に設定できますが、AsNoTracking()はすべてのクエリで使用する必要があります。そうでない場合、レコード(キーによる複製)はスキップされます。

9
crokusek

DBを変更する他の何か(別のプロセスなど)があり、これらの変更を確認する必要がある場合は、AsNoTracking()を使用します。クエリ:

http://codethug.com/2016/02/19/Entity-Framework-Cache-Busting/

6
andrew pate