AsNoTracking on context properties,query或ChangeTracker?

t3c*_*b0t 7 c# entity-framework-core

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

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

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

如果我以前AsNoTracking在每个上下文属性之后使用,现在我用最后一个查询替换它(或通过ChangeTracker它禁用它)它会产生相同的效果吗?

Iva*_*oev 6

AsNoTrackingAsTracking是 的扩展方法IQueryable<T>,因此与查询的状态相关联,而不是特定实体(它们在DbSet<T>级别可用的事实只是因为它实现了IQueryable<T>) - 注意方法描述中的all一词:

AsNoTracking

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

跟踪

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

两者都说:

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

换句话说,如果查询返回实体并且查询表达式树中的任何地方都没有AsNoTrackingAsTracking调用,则查询使用.ChangeTracker.QueryTrackingBehavior

因此,您的问题的答案是肯定的,您可以通过对最终查询的单个调用或通过ChangeTracker.

但是有一点需要注意,文档中没有解释。如果查询表达式树包含多个AsNoTracking/AsTracking调用,则最后一个调用优先。这意味着通过添加AsNoTracking或添加AsTracking到最终查询将控制它的行为,而不管任何内部跟踪行为调用或ChangeTracker属性。