AsNoTracking()背后是否有隐藏的功能?

时间:2015-10-08 15:22:21

标签: c# entity-framework

我正在处理一个大型项目(过去几年里,有许多不同的厨师制作汤)并且刚刚发现了以下代码。

private IEnumerable<string> SomeSome()
{
  using(DataModel context = DataModel())
  {
    context.SomeEntityName.AsNoTracking();
    ...
    return context.SomeEntityName
      .Where(entity => true)
      .Select(entity => String.Empty);
  }
}

现在,我已经检查了 AsNoTracking 方法和it's clearly said以返回与EF的跟踪设施没有业务关系的可查询对象。对于ORM来说,有点“火与难忘”,可以这么说。

注意到:

  1. 我们不存储价值,也不对返回者的内容做任何事情
  2. 我们获得了一个新的(显然可跟踪的)一组对象来做
  3. 的东西

    我想删除该行。然而,由于谦虚(即害怕人为害怕系统),我在删除任何内容之前都要谨慎。我的上下文中是否存在可能影响实体的第二次检索的隐式更改?

    我没有找到任何关于它的信息 - 既不赞成也不反对该理论。此外,我还没有找到任何其他版本的EF而不是5.0的文档(如上面的链接所示),但我们正在使用EF 6.1.3,我也知道有问题的方法也在EF 4中出现。

2 个答案:

答案 0 :(得分:3)

如果该行代码与项目完全相同,则没有任何变化。

context.SomeEntityName.AsNoTracking();

这^^^返回未保存在任何地方的可查询对象。如果删除该行,则对该行的查询没有任何区别。

<强> UPD 我查看了EF的源代码。据我所知AsNoTracking()并未改变您正在使用的DbContext对象的状态。因此,如果在一个查询上调用此方法,则不应该影响其他查询的执行。如果是的话 - 这是EF中的一个错误,应该报告。在我的项目中的多个位置,我有相同的dbContext查询跟踪和没有。一切都按预期工作。

来源:

答案 1 :(得分:0)

如果序列化此对象,则可能会发现如果定义了多对多关系,则会遇到问题。 AsNoTracking()调用可能已经到位,可以解决此问题,如下所示:

Serialization of Entity Framework objects with One to Many Relationship

平心而论,这有点像黑客,可以引导(正如你刚刚注意到的那样)人们想知道为什么在维护时会调用它。如果这是序列化的,那么最好有一个单独的可序列化DTO,而不是传递上下文对象本身。

我还要注意,已经有一些关于关闭跟踪以提高性能的讨论。根据您的要求,您可以在禁用跟踪时获得(显然)显着的性能提升。