追蹤 vs。不追蹤查詢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(). Entity Framework Core 將也 v-table 修正導覽屬性取得追蹤查詢的實體與先前已載入至 DbContext 執行個體的實體。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-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();
}

注意

沒有追蹤的查詢仍會執行識別解析內執行查詢。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. 如果具有相同識別是之前的結果超出範圍,而且執行記憶體回收,可能會收到新的實體執行個體。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
            });
}