.net .AsNoTracking()有什么区别?

irlmq6kh  于 2023-08-08  发布在  .NET
关注(0)|答案(6)|浏览(206)

我有一个关于.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步是一个更新,我猜无论如何都将命中数据库两次。
有谁能告诉我有什么区别吗?

yks3o0rb

yks3o0rb1#

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

qacovj5a

qacovj5a2#

见此页Entity Framework and AsNoTracking

AsNoTracking做什么

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

使用AsNoTracking可显著提高性能

ijxebb2r

ijxebb2r3#

无跟踪LINQ to Entities查询

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

优点

1.与常规LINQ查询相比提高了性能。
1.完全实体化的对象。
1.使用内置于编程语言中的语法编写最简单。
缺点
1.不适合CUD操作。
1.某些技术限制,例如:对OUTER JOIN查询使用DefaultIfEmpty的模式会导致比实体SQL中简单的OUTER JOIN语句更复杂的查询。
1.您仍然不能在常规模式匹配中使用LIKE。
更多信息可在这里:
Performance considerations for Entity Framework
Entity Framework and NoTracking

ef1yzkbh

ef1yzkbh4#

禁用跟踪还会导致结果集被流式传输到内存中。当您处理大型数据集并且不需要一次处理整个数据集时,这会更有效。
参考文献:

  • 使用Entity Framework和LINQ查询大型数据集时如何避免内存溢出
  • 实体框架大数据集,内存不足异常
xkftehaa

xkftehaa5#

AsNoTracking()允许绕过EF中的“每个记录唯一键”要求(其他答案没有明确提到)。
这在阅读不支持唯一键的视图时非常有用,因为某些字段可能是可空的,或者视图的性质在逻辑上是不可索引的。
对于这些情况,“key”可以设置为任何不可为空的列,但必须对每个查询使用AsNoTracking(),否则将跳过记录(按键重复)。

d7v8vwbk

d7v8vwbk6#

如果你有其他改变数据库的东西(比如说另一个进程),并且需要确保你看到这些改变,使用AsNoTracking(),否则EF可能会给予你上下文的最后一个副本,因此每次查询都使用一个新的上下文是很好的:
http://codethug.com/2016/02/19/Entity-Framework-Cache-Busting/

相关问题