C# 在实体框架中调用AsNoTracking的位置重要吗

C# 在实体框架中调用AsNoTracking的位置重要吗,c#,asp.net-mvc,performance,entity-framework,C#,Asp.net Mvc,Performance,Entity Framework,在编写实体框架查询时,在何处调用AsNoTracking方法重要吗?e、 g var matchingCustomers = context.Customers.AsNoTracking().Where(n => n.city == "Milan").Skip(50).Take(100).OrderBy(n => n.Name).ToList(); var matchingCustomers = context.Customers.Where(n => n.city == "M

在编写实体框架查询时,在何处调用AsNoTracking方法重要吗?e、 g

var matchingCustomers = context.Customers.AsNoTracking().Where(n => n.city == "Milan").Skip(50).Take(100).OrderBy(n => n.Name).ToList();
var matchingCustomers = context.Customers.Where(n => n.city == "Milan").AsNoTracking().Skip(50).Take(100).OrderBy(n => n.Name).ToList();
var matchingCustomers = context.Customers.Where(n => n.city == "Milan").Skip(50).AsNoTracking().Take(100).OrderBy(n => n.Name).ToList();
var matchingCustomers = context.Customers.Where(n => n.city == "Milan").Skip(50).Take(100).AsNoTracking().OrderBy(n => n.Name).ToList();
var matchingCustomers = context.Customers.Where(n => n.city == "Milan").Skip(50).Take(100).OrderBy(n => n.Name).AsNoTracking().ToList();
var matchingCustomers = context.Customers.Where(n => n.city == "Milan").Skip(50).Take(100).OrderBy(n => n.Name).ToList().AsNoTracking();
我喜欢将其添加到语句的末尾,但在调用ToList之前,如下所示:

var matchingCustomers = context.Customers.Where(n => n.city == "Milan").Skip(50).Take(100).OrderBy(n => n.Name).AsNoTracking().ToList();
不,没关系:

应用了NoTracking的新查询,如果不支持NoTracking,则为源查询

因此,您可以在开始时使用方法链展开“新建”查询,也可以在结束时执行此操作,然后获得“新建”查询。只要在执行查询之前调用,就可以了。

我认为

var matchingCustomers = context.Customers.Where(n => n.city == "Milan").Skip(50).Take(100).OrderBy(n => n.Name).ToList().AsNoTracking();
重要的是,一旦EF执行并跟踪了查询,您将尝试对内存中已经存在的数据结构应用NoTracking

当你使用这个流畅的API时;当然,在执行查询之前,您是在定义查询而不执行它
ToList()
将执行查询并将数据带到内存中,以将其转换为
列表
数据结构

让我们拆分命令以了解这一点:

  • 上下文。客户-->从客户中选择[*]
  • 其中(n=>n.city==“Milan”)-->从所在城市的客户中选择[*] ==‘米兰’
  • 跳过(50)。选择(100)->从客户中选择[*],其中城市=='Milan' 偏移量50行仅取下100行
  • OrderBy name-->从客户中选择[*],其中城市=='Milan' 偏移量50行仅取下100行按名称排序
  • ToList()-->执行查询并将数据带到内存中,默认情况下进行跟踪
  • AsNoTraking()-->不执行任何操作,因为EF已执行查询 并跟踪数据

实际上在最后一种情况下是这样的-在
ToList
之后调用
AsNoTracking
可能会抛出错误。如果没有,它实际上将是一个no op,因为在
AsNoTracking
出现时,实体已经在内存中了called@PanagiotisKanavos是的,这就是为什么我说“在执行查询之前”。
ToList()
执行查询。我用粗体显示link已失效,假设这是一个?@PanagiotisKanavos它不会是一个no-op。这将是一个编译时错误。你不能在ToList之后调用AsNoTracking,因为你不再有IQueryable来调用它。@AlexanderDerck你的实现被颠倒了。IQueryable实现了IEnumberable。在回答问题之前,请尝试做你将要谈论的事情。你不能在ToList之后调用AsNoTracking,因为你不再有一个IQueryable可以调用它。它会给出一个编译时错误。@Cdaragorn然后实际上什么都不做。;)物理上不可能编译不是“什么都不做”。