在AsNoTracking()后面是否有任何隐藏的功能?
本文关键字:隐藏 任何 功能 是否 AsNoTracking | 更新日期: 2023-09-27 18:16:50
我正在处理一个大项目(有许多不同的厨师在做汤,多年过去了),刚刚发现了下面的代码。
private IEnumerable<string> SomeSome()
{
using(DataModel context = DataModel())
{
context.SomeEntityName.AsNoTracking();
...
return context.SomeEntityName
.Where(entity => true)
.Select(entity => String.Empty);
}
}
现在,我已经三次检查了AsNoTracking方法,它清楚地说返回一个可查询的对象,它与EF的跟踪设施没有业务关系。可以说,这是ORM的一种"即发即忘"。
注意:
- 我们不存储值,也不处理返回值 的内容
- 我们获得一组新的(显然是可跟踪的)对象来处理
我想删除这一行。然而,作为一个谦虚的人(例如,不怕破坏系统),我在删除任何东西之前都很谨慎。在我的上下文中是否存在可能影响实体的第二次检索的隐式更改?
我没有找到任何关于它的信息——既不支持也不反对这个理论。此外,我还没有找到任何其他版本的EF 5.0的文档(如上面的链接所示),但我们正在使用EF 6.1.3,我知道问题的方法在EF 4中也存在。
如果这行代码与您的项目完全相同,那么就没有更改。
context.SomeEntityName.AsNoTracking();
this ^^^返回未保存在任何地方的可查询对象。如果您删除了这一行,那么下面的查询将不会有什么不同。
乌利希期刊指南我已经看了EF的源代码。据我所知,AsNoTracking()
不会改变DbContext
对象的状态。因此,如果在一个查询上调用该方法,它应该不会影响其他查询的执行。如果是这样,这是EF的一个bug,应该报告。在我的项目的多个地方,我有相同的dbContext
查询跟踪和没有。一切都如预期般顺利。
来源:
- DbQuery.AsNoTracking ()
- DbHelpers。CreateNoTrackingQuery
- TranslatorVisitor.Visit() Line 341+
如果序列化这个对象,那么如果定义了多对多关系,可能会遇到问题。AsNoTracking()
调用可能已经到位,以解决这个问题,如下所示:
具有一对多关系的实体框架对象序列化
平心而论,这是一个hack,可能导致(正如你刚刚注意到的)人们想知道为什么在维护时调用这个。如果这是序列化的,最好有一个单独的可序列化的DTO,而不是传递上下文对象本身。
我还注意到,已经有一些关于关闭跟踪以提高性能的讨论。根据您的目标,禁用跟踪可以(显然)显著提高性能。