.AsNoTracking()はどのような違いがありますか?


228

.AsNoTracking()これは非常に新しく、非常に混乱しているので、拡張機能について質問があります。

私はウェブサイトにリクエストごとのコンテキストを使用しています。

多くのエンティティは変更されないため、追跡する必要はありませんが、次のシナリオでは、データベースに何が送信されるか、またはこの場合に違いがあるかどうかさえ不明です。

この例は私が現在やっていることです:

context.Set<User>().AsNoTracking()
// Step 1) Get user
context.Set<User>()
// Step 2) Update user

これは上記と同じですが、.AsNoTracking()ステップ1からを削除します。

context.Set<User>();
// Step 1) Get user
context.Set<User>()
// Step 2) Update user

ステップ1と2は同じコンテキストを使用しますが、異なるタイミングで発生します。私が解決できないのは、違いがあるかどうかです。ステップ2は更新なので、どちらもデータベースに2回ヒットすることになると思います。

誰が私にその違いを教えてもらえますか?

回答:


187

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


1
context.Users.Select(u => new {Name = u.Name})のように、selectクエリの匿名クラスに同じ利点を得ることができますか?ありがとう。
Dilhan Jayathilake 2017

6
@DilhanJayathilake:匿名クラスはエンティティ自体を表さないため、追跡されません。
Ladislav Mrnka 2017

1
EF6はビューでエンティティキーを誤って推論することがあるので、AsNoTracking()はキーを無視するため、手動でキーを修正する代わりになります(キーの他の利点は必要ないと想定)。
crokusek 2017年

4
また、AsNoTrackingの最大の効果は、遅延読み込みが機能しないことです
Douglas Gaskell

170

このページを参照してくださいEntity Framework and AsNoTracking

AsNoTrackingの機能

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

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


11
利益が時々相殺することができるようだ:stackoverflow.com/questions/9259480/...
ファブリス

3
1ステップでincludeを使用して親子関係をロードする複雑なクエリによるパフォーマンスの向上は、約50%でした
Karl

53

LINQ to Entitiesクエリの追跡なし

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

長所

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

短所

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

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

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

エンティティフレームワークとNoTracking


34

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

参照:


10

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

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

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


2
ビューでこれの重要性を繰り返すために、SSMS経由で実行すると7つの一意のレコードを返すビューからのクエリがあります。AsNoTracking修飾子なしでEFを介して実行すると、最初のレコード、2番目の3つのコピー、3番目の3つのコピーが取得されます。これは修正するのに信じられないほど多くの頭を悩ませる必要があり、それを修正するAsNoTrackingを使用していました!
Ade

Linq to Entitiesを使用していて、主キーのないビューをクエリしているときに、まったく同じ問題が発生しました。AsNoTrackingについては、頭を悩ませてから半日後になって初めて知りました。このASP.Netフォーラムの投稿は、最終的に私を導きました。forums.asp.net/t/...
red_dorian

6

DBを変更する何か(別のプロセスなど)があり、これらの変更を確認する必要がある場合は、を使用しますAsNoTracking()。そうでない場合、EFはコンテキストの最後のコピーを代わりに提供する可能性があるため、通常はクエリごとに新しいコンテキストを使用することをお勧めします:

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.