テストプログラムなどで更新処理を実行するときにContextのTrackingが有効な場合、Contextから更新後のデータを取得するときに最初に取得した情報をContextが保持していてテストがFailになる事があります。忘れた頃に発生する事象で、たいてい急いでいるときにテスト対象のプログラムは正しいけどテストが通らないというつらい状況になったりします。
このようなケースでは最初にエンティティを取得するときにAsNoTracking
を設定すればOKです。
var personCustomer = CustomerContext.Context.Customers.AsNoTracking().Include(c => c.Person).Include(c => c.Organization) .First(c => c.Person != null);
とはいうものの、テストのように基本データを参照しかしないケースではデフォルトとしてAsNoTracking
を設定したいですよね。むしろ、Tracking
したいときにだけAsTracking
を設定することで余計なハマりをなくしたいわけです。
そこでContext単位でAsnoTracking
を一括で設定できる方法はないだろうかということになりますが、以下の通り設定すればContextに含まれるエンティティの取得がすべてTracking対象ではなくなります。
Context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
参考
以下の公式ドキュメントにもあるようにReadonlyとしてエンティティを使用する場合にはChangeTrackerの生成コストが小さくなるためおすすめのようです。
ChangeTracker Class (Microsoft.EntityFrameworkCore.ChangeTracking) | Microsoft Docs
Gets or sets the tracking behavior for LINQ queries run against the context. Disabling change tracking is useful for read-only scenarios because it avoids the overhead of setting up change tracking for each entity instance. You should not disable change tracking if you want to manipulate entity instances and persist those changes to the database using SaveChanges(). This method sets the default behavior for the context, but you can override this behavior for individual queries using the AsNoTracking
(IQueryable ) and AsTracking (IQueryable ) methods. The default value is TrackAll. This means the change tracker will keep track of changes for all entities that are returned from a LINQ query.
大人数で開発するときにはこの手のはまりは人数分のコストになるので、技術的に解決できるところはあらかじめ解決しておきたいですね。
追記
Npgsqlを利用している場合には、テスト対象データのバージョン番号を取得するためにはAsTracking
を設定する必要があります。
- 作者: 山本康彦
- 出版社/メーカー: 技術評論社
- 発売日: 2016/05/12
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (2件) を見る