.AsNoTracking()有什么区别?


228

我对.AsNoTracking()扩展名有疑问,因为这都是很新的,也很令人困惑。

我正在为网站使用每个请求的上下文。

我的许多实体都不会更改,因此不需要跟踪,但是在以下情况下,我不确定数据库的内容,甚至不确定在这种情况下是否有所作为。

这个例子是我目前正在做的:

context.Set<User>().AsNoTracking()
// Step 1) Get user
context.Set<User>()
// Step 2) Update user

与上面相同,但是.AsNoTracking()从步骤1中删除了:

context.Set<User>();
// Step 1) Get user
context.Set<User>()
// Step 2) Update user

步骤1和2使用相同的上下文,但是发生在不同的时间。我无法解决的是是否有任何区别。由于第2步是更新,因此我猜两者都将两次访问数据库。

谁能告诉我有什么区别?

Answers:


187

区别在于,在第一种情况下,上下文不会跟踪检索到的用户,因此当您要将用户保存回数据库时,必须附加它并正确设置用户状态,以便EF知道它应该更新现有用户而不是插入一个新的。在第二种情况下,如果使用相同的上下文实例加载和保存用户,则不需要这样做,因为跟踪机制会为您处理该情况。


1
我们可以为选择查询中的匿名类(例如context.Users.Select(u => new {Name = u.Name}))获得相同的好处吗?谢谢。
Dilhan Jayathilake

6
@DilhanJayathilake:匿名类不代表实体本身,因此没有跟踪。
Ladislav Mrnka '02

1
由于EF6有时会在View上错误地推断出实体密钥,因此AsNoTracking()会忽略该密钥,因此是手动修复密钥的替代方法(假设不需要密钥的其他好处)。
crokusek

4
另请注意,AsNoTracking的最大影响是延迟加载将不起作用
Douglas Gaskell

170

参见本页实体框架和AsNoTracking

AsNoTracking会做什么

实体框架公开了许多性能调整选项,以帮助您优化应用程序的性能。这些调整选项之一是.AsNoTracking()。通过这种优化,您可以告诉您Entity Framework不要跟踪查询结果。这意味着Entity Framework不对查询返回的实体执行任何其他处理或存储。但是,这也意味着您必须先将这些实体重新附加到跟踪图上,才能更新它们。

使用AsNoTracking可以显着提高性能


11
似乎有时有时会抵消收益:stackoverflow.com/questions/9259480/…–
Fabrice

3
通过复杂的查询加载包含一个步骤的父子关系的性能提高了大约50%
Karl

53

没有跟踪LINQ到实体查询

当查询用于读取操作时,建议使用AsNoTracking()。在这些情况下,您可以取回您的实体,但是它们不会被上下文跟踪,这可以确保最小的内存使用量和最佳性能

优点

  1. 与常规LINQ查询相比,性能得到了提高。
  2. 完全物化的对象。
  3. 使用编程语言内置的语法最简单地编写。

缺点

  1. 不适合CUD操作。
  2. 某些技术限制,例如:与Entity SQL中的简单OUTER JOIN语句相比,对OUTER JOIN查询使用DefaultIfEmpty的模式所导致的查询更为复杂。
  3. 您仍然不能将LIKE与常规模式匹配一​​起使用。

此处提供更多信息:

实体框架的性能注意事项

实体框架和NoTracking



10

AsNoTracking()允许绕过EF中的“每条记录唯一键”要求(其他答案未明确提及)。

这在读取不支持唯一键的View时非常有用,因为某些字段可能为空,或者该视图的性质在逻辑上不可索引。

对于这些情况,“键”可以设置为任何不可为空的列,但随后每个查询都必须使用AsNoTracking(),否则将跳过记录(按键重复)。


2
只是为了重申使用Views的重要性,我有一个视图查询,该视图通过SSMS运行时返回7个唯一记录。当通过EF运行时,如果没有AsNoTracking修改器,我将得到第一条记录,第二条记录的三个副本,第三条记录的三个副本。这需要花费大量的时间来解决,并且使用了AsNoTracking来解决!
阿德

查询没有主键的View时使用Linq to Entities时,我遇到了完全相同的问题。经过半天的反复摸索才发现有关AsNoTracking的信息。这个ASP.Net论坛帖子最终将我引向了它。forums.asp.net/t/...
red_dorian

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.