是否调用实体框架中的AsNoTracking是否重要?

时间:2016-02-22 12:17:47

标签: 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 == "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();

2 个答案:

答案 0 :(得分:15)

不,这不重要:(source)

  

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

所以你要么在开始时做,要扩展" new"使用方法链进行查询,或者最后进行查询,然后获取" new"查询。只要您在执行查询之前将其称为 ,您就可以了。

答案 1 :(得分:6)

我认为

var matchingCustomers = context.Customers.Where(n => n.city == "Milan").Skip(50).Take(100).OrderBy(n => n.Name).ToList().AsNoTracking();

很重要,因为一旦EF执行并追踪查询,你就试图将NoTracking应用于已经存储在内存中的数据结构。

使用这种流畅的API时;您正在定义查询而不执行它,直到您执行查询为止。 ToList()将执行查询并将数据带入内存以将其转换为List<T>数据结构。

让我们分开命令来理解这一点:

  • context.Customers - &gt;从客户
  • 中选择[*]
  • 其中(n =&gt; n.city ==“米兰”) - &gt;从城市的客户中选择[*] =='米兰'
  • Skip(50).Take(100) - &gt;从城市=='米兰'的客户中选择[*] OFFSET 50 ROWS FETCH NEXT 100行仅
  • OrderBy name - &gt;从城市=='米兰'的客户中选择[*] OFFSET 50 ROWS FETCH NEXT 100行仅按名称排序
  • ToList() - &gt;执行查询并将数据带入内存,默认情况下为Tracking!
  • AsNoTraking() - &gt;什么都没有,因为EF已经执行了查询 并跟踪数据。