.AsNoTracking()有什么区别?

我有一个关于.AsNoTracking()扩展的问题,因为这都是非常新的和令人困惑的。

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

我的许多实体没有改变,所以不需要跟踪,但我有以下场景,我不确定什么将进入数据库,甚至在这种情况下它是否有区别。

以下是我目前正在做的事情:

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

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

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

步骤1 &使用相同的上下文,但出现在不同的时间。我弄不明白的是是否有什么不同。由于第2步是一个更新,我猜无论如何都将击中数据库两次。

有人能告诉我有什么不同吗?

234638 次浏览

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

禁用跟踪还会导致结果集流到内存中。当您处理大量数据且不需要一次性使用整个数据集时,这将更加高效。

引用:

参见本页实体框架和AsNoTracking

AsNoTracking做什么

实体框架提供了许多性能调优选项,以帮助您优化应用程序的性能。其中一个调优选项是.AsNoTracking()。这个优化允许你告诉Entity Framework不跟踪查询的结果。这意味着Entity Framework不会对查询返回的实体执行额外的处理或存储。然而,这也意味着您不能在不将这些实体重新附加到跟踪图的情况下更新它们。

使用AsNoTracking可以显著提高性能

没有跟踪LINQ到实体查询

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

优点

  1. 改进了常规LINQ查询的性能。
  2. 完全物化的物体。
  3. 用编程中内置的语法编写最简单 李语言。< / >

缺点

  1. 不适合CUD操作。
  2. 某些技术限制,例如:模式使用DefaultIfEmpty for OUTER JOIN查询的结果比简单的OUTER查询更复杂
  3. . JOIN语句
  4. 您仍然不能对一般模式匹配使用LIKE。

更多信息可在这里:

实体框架的性能考虑

< a href = " http://blog.staticvoid.co。nz/2012/4/2/entity_framework_and_asnotracking" rel="noreferrer">实体框架和NoTracking . nz/2012/4/2/entity_framework_and_asnotracking" rel="noreferrer">实体框架和NoTracking

如果你有其他东西改变了DB(比如另一个进程),并且需要确保你看到这些变化,使用AsNoTracking(),否则EF可能会给你你的上下文拥有的最后一个副本,因此通常每次查询使用一个新的上下文是很好的:

http://codethug.com/2016/02/19/Entity-Framework-Cache-Busting/

AsNoTracking()允许EF中的“每条记录的唯一键”需求被绕过(其他答案没有明确提到)。

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

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