在实体框架中调用 AsNoTracking 的位置是否重要

本文关键字:位置 是否 AsNoTracking 实体 框架 调用 | 更新日期: 2023-09-27 18:35:37

在编写实体框架查询时调用 AsNoTracking 方法的位置是否重要?例如

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();

在实体框架中调用 AsNoTracking 的位置是否重要

不,

没关系:(来源)

应用了"无跟踪"的新查询,或不支持"无跟踪"的源查询。

因此,您要么在开始时执行此操作,然后使用方法链扩展"new"查询,要么在最后执行此操作,然后获得"new"查询。只要在执行查询之前调用它就可以了。

正如Cdaragorn在评论中所说。

您不能在ToList之后调用AsNoTracking,因为您不再拥有一个智商可以调用它。它将给出编译时错误。

在您可以执行OP要求的情况下,我将解释查询将如何工作,因为可以帮助其他人理解这些问题:

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>数据结构。

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

  • 上下文。客户 --> 从客户中选择 [*]
  • 地点(n => n.city == "米兰") --> 从客户中选择 [*] 哪个城市== "米兰"
  • 跳过(50).Take(100) --> 从城市 == '米兰' 的客户中选择 [*]偏移 50 行仅提取接下来的 100 行
  • 按名称排序 --> 从城市 == "米兰"的客户中选择 [*]偏移 50 行 仅获取接下来的 100 行 按名称排序
  • ToList() --> 执行查询并将数据放入内存中,默认使用跟踪!
  • AsNoTraking() --> 不执行任何操作,因为 EF 已经执行了查询并跟踪数据。