AsNoTracking()和Include

Jua*_*mez 28 c# linq entity-framework

我有一个Linq查询,用于获取实体及其某些导航属性.

context.MyEntity
    .AsNoTracking()
    .Include(i=> i.Nav1)
    .Include(i=> i.Nav2)
    .Where(x=> x.Prop1==1)
    .FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)

我的问题是:

以上查询是否足以不跟踪MyEntity导航属性NAv1和/ Nav2或我必须AsNoTracking为每个导航属性添加?

像这样:  

context.MyEntity
    .AsNoTracking()
    .Include(i=> i.Nav1)
    .AsNoTracking()
    .Include(i=> i.Nav2)
    .AsNoTracking()
    .Where(x=> x.Prop1==1)
    .FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)

Dan*_*iel 28

在完成所有查询参数之后但在将数据移动到内存之前使用AsNoTracking.在此示例中,您将需要:

context.MyEntity
    .Include(i=> i.Nav1)
    .Include(i=> i.Nav2)
    .Where(x=> x.Prop1==1)
    .AsNoTracking()
    .FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)

不会跟踪父实体的任何子对象.

  • 危险推荐。由于默认情况下启用更改跟踪,因此集中禁用此功能可能会使整个团队感到沮丧,而他们却没有意识到是什么影响了他们的工作。假设当您对对象状态进行更改时,它们将在保存时持久化,这也是很自然的。全局禁用可能会导致创建意外的孤立记录,这是一个可能影响生产的问题,直到为时已晚才被发现。出于某种原因,更改跟踪是默认设置。 (14认同)
  • 在.net核心中,考虑使用`context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;`禁用跟踪行为,将其作为配置而不是查询的属性。 (4认同)
  • @hunter 警告做得很好,但肯定有合适的时间使用它,例如在长只读操作或只读应用程序中。代码与意图相匹配很重要。 (4认同)
  • 另外,也许值得一提的是,“AsNoTracking()”可以在 LINQ 语句中的任何位置使用。并不是绝对有必要将其放在最后。它总是关闭对整个语句的跟踪。上面第一条评论的第一部分(“每个查询只需要 AsNoTracking 一次,因此您的第一个示例是正确的。”)是正确的。 (4认同)
  • @Daniel 请注意,目前在某些情况下 `.AsNoTracking()` 会比 `.AsTracking()` 慢。https://github.com/aspnet/EntityFrameworkCore/issues/14366 (3认同)
  • @BenjaminBrandt 在发表此评论时,我的回答根本不适用于 EF Core。 (2认同)
  • 看起来这不会同时跟踪子对象和父实体。有没有办法跟踪父母而不是孩子? (2认同)