我注意到可以通过三种不同的方式禁用跟踪:
AsNoTracking
的上下文属性AsNoTracking
进行操作context.ChangeTracker.QueryTrackingBehavior
如果要禁用对所有内容的跟踪,这三种方法之间是否有区别?
如果我以前在每个上下文属性之后使用了AsNoTracking
,现在我只用对最终查询的一个调用替换了它(或通过ChangeTracker
禁用了它),是否会有相同的效果? / p>
答案 0 :(得分:3)
AsNoTracking
和AsTracking
是IQueryable<T>
的扩展方法,因此与查询的状态相关联,而不是特定的实体(它们在{{1}处可用) }级仅仅是因为它实现了DbSet<T>
)-请注意方法说明中的 all 一词:
AsNoTracking
返回一个新查询,其中更改跟踪器将不跟踪任何返回的实体。
AsTracking
返回一个新查询,更改跟踪器将跟踪所有返回实体的更改。
两个都说:
查询的默认跟踪行为可以由QueryTrackingBehavior控制。
换句话说,如果查询返回实体并且在查询表达式树中没有IQueryable<T>
或AsNoTracking
调用 anywhere ,则查询将使用{ {1}}。
因此,您的问题的答案是肯定的。您可以通过对最终查询的一次调用或通过AsTracking
来达到相同的效果。
但是要注意一件事,文档中没有对此进行说明。如果查询表达式树包含多个ChangeTracker.QueryTrackingBehavior
/ ChangeTracker
调用,则 last 调用优先。这意味着通过在最终查询中添加AsNoTracking
或AsTracking
可以控制其行为,而不管任何内部跟踪行为调用或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();
}