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

dot*_*oob 211 .net c# entity-framework entity-framework-4.3

我有一个关于.AsNoTracking()扩展的问题,因为这一切都很新而且很混乱.

我正在使用网站的每请求上下文.

我的很多实体都没有改变,所以不需要跟踪,但我有以下场景,我不确定数据库会发生什么,甚至在这种情况下它是否有所不同.

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

context.Set<User>().AsNoTracking()
// Step 1) Get user
context.Set<User>()
// Step 2) Update user
Run Code Online (Sandbox Code Playgroud)

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

context.Set<User>();
// Step 1) Get user
context.Set<User>()
// Step 2) Update user
Run Code Online (Sandbox Code Playgroud)

步骤1和2使用相同的上下文,但在不同的时间发生.我无法解决的是,是否存在任何差异.由于步骤2是更新,我猜两个都会打两次数据库.

谁能告诉我有什么区别?

Lad*_*nka 169

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

  • @DilhanJayathilake:匿名类不代表实体本身,因此他们没有跟踪. (4认同)
  • 我们能否在 select 查询中获得与匿名类相同的好处,例如 context.Users.Select(u=&gt; new { Name = u.Name })?谢谢。 (3认同)
  • 另请注意,AsNoTracking的最大效果是延迟加载不起作用 (3认同)

Moj*_*oji 155

请参阅此页实体框架和AsNoTracking

AsNoTracking的作用

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

使用AsNoTracking可以获得显着的性能提升

  • 似乎有时可以平衡收益:http://stackoverflow.com/questions/9259480/entity-framework-mergeoption-notracking-bad-performance (10认同)
  • 通过复杂的查询一步加载包含父子关系的我的性能提升约为50% (2认同)
  • 2022 年的另一个反馈:使用 AsNoTracking()(实体框架 6)获得了“巨大”收益。实际上出于其他原因 - 此处不公开详细信息,但它与 EF 的 Include() 方法有关 - 我已禁用跟踪,而不是对我正在使用的关于我正在执行的特定 linq 查询的 DbContext 使用 AsNoTracking()我的情况:ctx.Configuration.AutoDetectChangesEnabled = false;)。我想说,性能提升至少为 95%,甚至可能更多(我并没有高估:执行时间从超过 1 小时减少到不到 15 秒......) (2认同)

Nul*_*nce 46

无跟踪LINQ to Entities查询

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

优点

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

缺点

  1. 不适合CUD操作.
  2. 某些技术限制,例如:对于OUTER JOIN查询使用DefaultIfEmpty的模式导致比Entity SQL中的简单OUTER JOIN语句更复杂的查询.
  3. 您仍然无法使用LIKE与一般模式匹配.

更多信息在这里:

实体框架的性能注意事项

实体框架和NoTracking


Ron*_*rby 32

禁用跟踪还会导致结果集流入内存.当您处理大量数据并且不需要同时使用整个数据集时,这会更有效.

参考文献:


cro*_*sek 10

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

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

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

  • 为了重申使用Views的重要性,我从一个视图中查询,该视图在通过SSMS运行时返回7个唯一记录.当通过EF运行时,没有AsNoTracking修饰符,我得到第一个记录,第三个记录的三个副本和第三个记录的三个副本.这需要很多令人难以置信的头脑修复,它正在使用AsNoTracking修复它! (2认同)

and*_*ate 6

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

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