C# .AsNoTracking() 有什么区别?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12211680/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 22:28:49  来源:igfitidea点击:

What difference does .AsNoTracking() make?

c#.netentity-frameworkentity-framework-4.3

提问by dotnetnoob

I have a question regarding the .AsNoTracking()extension, as this is all quite new and quite confusing.

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

I'm using a per-request context for a website.

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

A lot of my entities don't change so don't need to be tracked, but I have the following scenario where I'm unsure of what's going to the database, or even whether it makes a difference in this case.

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

This example is what I'm currently doing:

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

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

This is the same as above but removing the .AsNoTracking()from Step 1:

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

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

The Steps 1 & 2 use the same context but occur at different times. What I can't work out is whether there is any difference. As Step 2 is an update I'm guessing both will hit the database twice anyway.

步骤 1 和 2 使用相同的上下文,但发生在不同的时间。我无法弄清楚是否有任何区别。由于第 2 步是更新,我猜无论如何都会两次访问数据库。

Can anyone tell me what the difference is?

谁能告诉我有什么区别?

采纳答案by Ladislav Mrnka

The difference is that in the first case the retrieved user is not tracked by the context so when you are going to save the user back to database you must attach it and set correctly state of the user so that EF knows that it should update existing user instead of inserting a new one. In the second case you don't need to do that if you load and save the user with the same context instance because the tracking mechanism handles that for you.

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

回答by Ronnie Overby

Disabling tracking will also cause your result sets to be streamed into memory. This is more efficient when you're working with large sets of data and don't need the entire set of data all at once.

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

References:

参考:

回答by Moji

see this page Entity Framework and AsNoTracking

请参阅此页面实体框架和 AsNoTracking

What AsNoTracking Does

AsNoTracking 的作用

Entity Framework exposes a number of performance tuning options to help you optimise the performance of your applications. One of these tuning options is .AsNoTracking(). This optimisation allows you to tell Entity Frameworknot to track the results of a query. This means that Entity Frameworkperforms no additional processing or storage of the entities which are returned by the query. However, it also means that you can't update these entities without reattaching them to the tracking graph.

Entity Framework 公开了许多性能调优选项,以帮助您优化应用程序的性能。这些调整选项之一是.AsNoTracking(). 此优化允许您告诉Entity Framework不要跟踪查询的结果。这意味着Entity Framework不会对查询返回的实体执行额外的处理或存储。但是,这也意味着您无法在不将它们重新附加到跟踪图的情况下更新这些实体。

there are significant performance gains to be had by using AsNoTracking

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

回答by NullReference

No Tracking LINQ to Entities queries

没有跟踪 LINQ to Entities 查询

Usage of AsNoTracking() is recommended when your query is meant for read operations. In these scenarios, you get back your entities but they are not tracked by your context.This ensures minimal memory usage and optimal performance

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

Pros

  1. Improved performance over regular LINQ queries.
  2. Fully materialized objects.
  3. Simplest to write with syntax built into the programming language.

Cons

  1. Not suitable for CUD operations.
  2. Certain technical restrictions, such as: Patterns using DefaultIfEmpty for OUTER JOIN queries result in more complex queries than simple OUTER JOIN statements in Entity SQL.
  3. You still can't use LIKE with general pattern matching.

优点

  1. 提高了常规 LINQ 查询的性能。
  2. 完全物化的对象。
  3. 使用编程语言中内置的语法编写最简单。

缺点

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

More info available here:

此处提供更多信息:

Performance considerations for Entity Framework

实体框架的性能注意事项

Entity Framework and NoTracking

实体框架和 NoTracking

回答by andrew pate

If you have something else altering the DB (say another process) and need to ensure you see these changes, use AsNoTracking(), otherwise EF may give you the last copy that your context had instead, hence it being good to usually use a new context every query:

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

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

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

回答by crokusek

AsNoTracking() allows the "unique key per record" requirement in EF to be bypassed (not mentioned explicitly by other answers).

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

This is extremely helpful when reading a View that does not support a unique key because perhaps some fields are nullable or the nature of the view is not logically indexable.

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

For these cases the "key" can be set to any non-nullable column but then AsNoTracking() must be used with every query else records (duplicate by key) will be skipped.

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