我对.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是一个更新,我猜两个都会在数据库中两次。
谁能告诉我有什么区别?
答案 0 :(得分:151)
不同之处在于,在第一种情况下,上下文不会跟踪检索到的用户,因此当您要将用户保存回数据库时,您必须附加它并正确设置用户的状态,以便EF知道它应该更新现有用户而不是插入新用户。在第二种情况下,如果您使用相同的上下文实例加载并保存用户,则不需要这样做,因为跟踪机制会为您处理。
答案 1 :(得分:140)
请参阅此页Entity Framework and AsNoTracking
Entity Framework提供了许多性能调优选项,可帮助您优化应用程序的性能。其中一个调整选项是.AsNoTracking()
。通过此优化,您可以告诉Entity Framework
不要跟踪查询结果。这意味着Entity Framework
不执行查询返回的实体的额外处理或存储。但是,这也意味着如果不将这些实体重新连接到跟踪图,则无法更新这些实体。
使用AsNoTracking
可以带来显着的性能提升答案 2 :(得分:38)
无跟踪LINQ to Entities查询
当您的查询用于读取操作时,建议使用AsNoTracking()。在这些情况下,您可以返回实体,但不会被您的上下文跟踪。这可以确保最少的内存使用和最佳性能
<强>赞成强>
- 比常规LINQ查询提高了性能。
- 完全物化的物体。
- 最简单的编写语法内置编程 语言。
醇><强>缺点强>
- 不适合CUD操作。
- 某些技术限制,例如:使用DefaultIfEmpty的模式 OUTER JOIN查询导致比简单OUTER更复杂的查询 实体SQL中的JOIN语句。
- 您仍然无法使用LIKE进行常规模式匹配。
醇>
此处提供更多信息:
答案 3 :(得分:31)
禁用跟踪还会将结果集流式传输到内存中。当您处理大量数据并且不需要同时使用整个数据集时,这会更有效。
参考文献:
答案 4 :(得分:9)
AsNoTracking()允许绕过EF中的“每条记录的唯一密钥”要求(其他答案未明确提及)。
这在阅读不支持唯一键的视图时非常有用,因为某些字段可能是可空的,或者视图的性质在逻辑上不可索引。
对于这些情况,“key”可以设置为任何非可空列,但是AsNoTracking()必须与每个查询一起使用,否则将跳过其他记录(按键复制)。
答案 5 :(得分:6)
如果您还有其他更改数据库(说另一个进程)并需要确保您看到这些更改,请使用AsNoTracking()
,否则EF可能会为您提供上下文的最后一个副本,因此它很好通常在每个查询中使用新的上下文:
http://codethug.com/2016/02/19/Entity-Framework-Cache-Busting/