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使用相同的上下文,但发生在不同的时间。 我不能解决的是是否有任何区别。 由于第2步是更新,我猜两者无论如何都会触发数据库两次。

谁能告诉我有什么不同?

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

看到这个页面entity framework和AsNoTracking

AsNoTracking做什么

Entity Framework公开了许多性能调优选项,以帮助您优化应用程序的性能。 其中一个调优选项是.AsNoTracking()。 此优化允许您告知entity framework不要跟踪查询的结果。 这意味着entity framework不会对查询返回的实体进行额外的处理或存储。 但是这也意味着你不能更新这些实体而不将它们重新附加到跟踪图上。

使用AsNoTracking有显着的性能提升

禁用跟踪也将导致您的结果集stream入内存。 当您处理大量数据并且不需要同时存储整个数据集时,这会更有效率。

参考文献:

  • 当使用entity framework和LINQ查询大型数据集时,如何避免内存溢出
  • 大型数据集entity framework,内存不足exception

没有跟踪LINQ to Entities查询

当您的查询用于读取操作时,build议使用NoTracking()。 在这些情况下,您将取回您的实体,但不会根据您的上下文进行跟踪。这确保了最小的内存使用量和最佳性能

优点

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

缺点

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

更多信息在这里:

对entity framework的性能考虑

entity framework和无跟踪

如果你还有别的东西在改变数据库(比如另一个进程),并且需要确保你看到了这些改变,那就使用AsNoTracking(),否则EF会给你最后一个你的上下文的副本,所以通常使用新的上下文每个查询:

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