AsNoTracking有关上下文属性,查询还是ChangeTracker?

时间:2018-09-19 07:59:45

标签: c# entity-framework-core

我注意到可以通过三种不同的方式禁用跟踪:

  • 通过AsNoTracking的上下文属性
  • 在执行最终查询之前通过AsNoTracking进行操作
  • 通过context.ChangeTracker.QueryTrackingBehavior

如果要禁用对所有内容的跟踪,这三种方法之间是否有区别?

如果我以前在每个上下文属性之后使用了AsNoTracking,现在我只用对最终查询的一个调用替换了它(或通过ChangeTracker禁用了它),是否会有相同的效果? / p>

2 个答案:

答案 0 :(得分:3)

AsNoTrackingAsTrackingIQueryable<T>的扩展方法,因此与查询的状态相关联,而不是特定的实体(它们在{{1}处可用) }级仅仅是因为它实现了DbSet<T>)-请注意方法说明中的 all 一词:

AsNoTracking

  

返回一个新查询,其中更改跟踪器将不跟踪任何返回的实体。

AsTracking

  

返回一个新查询,更改跟踪器将跟踪所有返回实体的更改。

两个都说:

  

查询的默认跟踪行为可以由QueryTrackingBehavior控制。

换句话说,如果查询返回实体并且在查询表达式树中没有IQueryable<T>AsNoTracking调用 anywhere ,则查询将使用{ {1}}。

因此,您的问题的答案是肯定的。您可以通过对最终查询的一次调用或通过AsTracking来达到相同的效果。

但是要注意一件事,文档中没有对此进行说明。如果查询表达式树包含多个ChangeTracker.QueryTrackingBehavior / ChangeTracker调用,则 last 调用优先。这意味着通过在最终查询中添加AsNoTrackingAsTracking可以控制其行为,而不管任何内部跟踪行为调用或AsNoTracking属性如何。

答案 1 :(得分:1)

AsNoTracking适用于单个查询级别

using (var context = new YourContext())
{
    var data = context.Entity
        .AsNoTracking()
        .ToList();
}

您还可以在上下文实例级别更改默认跟踪行为:

如果要在上下文实例级别执行此操作,则可以这样做,与EF 6不同(每次进行查询时,AsNoTracking()是必需的):

using (var context = new YourContext())
{
    context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
    var data = context.Entity.ToList();
}