有什么不同.AsNoTracking()会做什么?

时间:2012-08-31 08:35:23

标签: c# .net entity-framework entity-framework-4.3

我对.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&amp; 2使用相同的上下文但在不同的时间发生。我无法解决的是,是否存在任何差异。由于步骤2是一个更新,我猜两个都会在数据库中两次。

谁能告诉我有什么区别?

6 个答案:

答案 0 :(得分:151)

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

答案 1 :(得分:140)

请参阅此页Entity Framework and AsNoTracking

AsNoTracking的作用

Entity Framework提供了许多性能调优选项,可帮助您优化应用程序的性能。其中一个调整选项是.AsNoTracking()。通过此优化,您可以告诉Entity Framework不要跟踪查询结果。这意味着Entity Framework不执行查询返回的实体的额外处理或存储。但是,这也意味着如果不将这些实体重新连接到跟踪图,则无法更新这些实体。

使用AsNoTracking

可以带来显着的性能提升

答案 2 :(得分:38)

无跟踪LINQ to Entities查询

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

  

<强>赞成

     
      
  1. 比常规LINQ查询提高了性能。
  2.   
  3. 完全物化的物体。
  4.   
  5. 最简单的编写语法内置编程   语言。
  6.         

    <强>缺点

         
        
    1. 不适合CUD操作。
    2.   
    3. 某些技术限制,例如:使用DefaultIfEmpty的模式   OUTER JOIN查询导致比简单OUTER更复杂的查询   实体SQL中的JOIN语句。
    4.   
    5. 您仍然无法使用LIKE进行常规模式匹配。
    6.   

此处提供更多信息:

Performance considerations for Entity Framework

Entity Framework and NoTracking

答案 3 :(得分:31)

禁用跟踪还会将结果集流式传输到内存中。当您处理大量数据并且不需要同时使用整个数据集时,这会更有效。

参考文献:

答案 4 :(得分:9)

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

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

对于这些情况,“key”可以设置为任何非可空列,但是AsNoTracking()必须与每个查询一起使用,否则将跳过其他记录(按键复制)。

答案 5 :(得分:6)

如果您还有其他更改数据库(说另一个进程)并需要确保您看到这些更改,请使用AsNoTracking(),否则EF可能会为您提供上下文的最后一个副本,因此它很好通常在每个查询中使用新的上下文:

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