Vs を追跡します。No 追跡クエリTracking vs. No-Tracking Queries

Entity Framework Core は、変更トラッカーのエンティティのインスタンスに関する情報を保持するかどうかは、コントロールの動作を追跡します。Tracking behavior controls whether or not Entity Framework Core will keep information about an entity instance in its change tracker. エンティティで検出されたすべての変更を中にデータベースに永続化のエンティティを管理している場合SaveChanges()です。If an entity is tracked, any changes detected in the entity will be persisted to the database during SaveChanges(). 追跡クエリから取得されたエンティティと DbContext インスタンスに以前に読み込まれたエンティティの間エンティティ Framework Core もフィックス アップ ナビゲーション プロパティ。Entity Framework Core will also fix-up navigation properties between entities that are obtained from a tracking query and entities that were previously loaded into the DbContext instance.

ヒント

この記事を表示するサンプルGitHub でします。You can view this article's sample on GitHub.

追跡クエリTracking queries

既定では、エンティティ型を返すクエリを追跡します。By default, queries that return entity types are tracking. つまり、これらのエンティティのインスタンスに変更を加えることができますが、によって保存されたこれらの変更SaveChanges()です。This means you can make changes to those entity instances and have those changes persisted by SaveChanges().

次の例では、ブログの規制への変更が検出され、中にデータベースに永続化SaveChanges()です。In the following example, the change to the blogs rating will be detected and persisted to the database during SaveChanges().

using (var context = new BloggingContext())
{
    var blog = context.Blogs.SingleOrDefault(b => b.BlogId == 1);
    blog.Rating = 5;
    context.SaveChanges();
}

No 追跡クエリNo-tracking queries

追跡クエリはありません便利結果を読み取り専用のシナリオで使用されます。No tracking queries are useful when the results are used in a read-only scenario. これらは、セットアップの変更情報を追跡する必要はありませんので、実行する方が手軽です。They are quicker to execute because there is no need to setup change tracking information.

なしの追跡に、個々 のクエリを交換することができます。You can swap an individual query to be no-tracking:

using (var context = new BloggingContext())
{
    var blogs = context.Blogs
        .AsNoTracking()
        .ToList();
}

既定のインスタンス レベルのコンテキストの動作を追跡を変更することもできます。You can also change the default tracking behavior at the context instance level:

using (var context = new BloggingContext())
{
    context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;

    var blogs = context.Blogs.ToList();
}

注意

追跡クエリには引き続き実行クエリ内の id 解決を実行しません。No tracking queries still perform identity resolution within the excuting query. 結果セットには、複数回には、同じエンティティが含まれています場合、は、結果セットに発生するたびに、そのエンティティ クラスの同じインスタンスが返されます。If the result set contains the same entity multiple times, the same instance of the entity class will be returned for each occurrence in the result set. ただし、弱い参照は、返されたエンティティの追跡に使用されます。However, weak references are used to keep track of entities that have already been returned. 同じ id を持つ前の結果がスコープ外に出るし、ガベージ コレクションの実行する場合、は、エンティティの新しいインスタンスを取得可能性があります。If a previous result with the same identity goes out of scope, and garbage collection runs, you may get a new entity instance. 詳細については、次を参照してください。クエリのしくみです。For more information, see How Query Works.

追跡と予測Tracking and projections

結果には、エンティティ型が含まれている場合、クエリの結果の型に、エンティティ型がされていない場合でも引き続き追跡される既定です。Even if the result type of the query isn't an entity type, if the result contains entity types they will still be tracked by default. 次のクエリで、匿名型のインスタンスが返されますBlog結果セットの追跡に使用されます。In the following query, which returns an anonymous type, the instances of Blog in the result set will be tracked.

using (var context = new BloggingContext())
{
    var blog = context.Blogs
        .Select(b =>
            new
            {
                Blog = b,
                Posts = b.Posts.Count()
            });
}

結果セットに、エンティティ型が含まれていない場合は、追跡は行われません。If the result set does not contain any entity types, then no tracking is performed. 匿名型が返されます次のクエリでは、エンティティ (ただし、実際のエンティティ型のインスタンスがない) からの値の一部ではありません追跡実行されます。In the following query, which returns an anonymous type with some of the values from the entity (but no instances of the actual entity type), there is no tracking performed.

using (var context = new BloggingContext())
{
    var blog = context.Blogs
        .Select(b =>
            new
            {
                Id = b.BlogId,
                Url = b.Url
            });
}