什么会触发Entity Framework修复导航属性?

6

我找不到关于Entity Framework在何时设置外键时查找正确相关对象的好文档。

我正在使用延迟加载(但没有更改跟踪)代理。设置外键,然后获取导航属性值返回null,即使相关导航对象已经加载并存在于DbContext中。

调用DetectChanges可以解决问题,但似乎比较耗费资源。是否有其他方法可以提示Entity Framework进行修复?

2个回答

7

你说得对。 DetectChanges 是触发关系修复的方法。如果出于任何原因想要进行关系修复,可以调用 DetectChanges

但是,当执行以下方法时,EF也会自动调用 DetectChanges:

  • DbSet.Add
  • DbSet.Find
  • DbSet.Remove
  • DbSet.Local
  • DbContext.SaveChanges
  • DbSet.Attach
  • DbContext.GetValidationErrors
  • DbContext.Entry
  • DbChangeTracker.Entries
  • 针对 DbSet 运行任何 LINQ 查询

(来自 Lerman & Miller 的书籍 DbContext,第 60 页)。

正如你看到的,在设置外键值后,几乎所有与 EF 相关的操作都将调用 DetectChanges,因此如果之后还有其他有用的操作,请先执行这些操作以节省一次 DetectChanges 调用。


那么,DetectChanges调用的是否有一种方法可以进行修复而无需进行完整的更改检测? - jnm2
不,ObjectStateManager 只有一个私有方法 AlignChangesInRelationships,它被用于 DetectChanges 中调用。但这确实是最有效的方式,先检测变化,然后修复受这些变化影响的关系。并非所有关系都会受到影响。 - Gert Arnold
对于变更通知跟踪,我认为 EF 在发生变更通知时会修复关系。 - sjb-sjb

1
使用更改跟踪实体时,其中一个导航属性对的修复会在设置另一个导航时进行。例如,假设从帖子到博客有一个主要实体导航,并且从博客到帖子有一个从属集合属性。如果您正在使用更改跟踪实体,则设置post.Blog = blog也将导致blog.Posts.Add(post)。如果您习惯于在SaveChanges之前在代码中执行post.Blog = blog和然后是blog.Posts.Add(post),那么这可能会有点令人困惑。当您使用DetectChanges时,这是无害的,但是使用更改跟踪实体时,在SaveChanges之前,您将在blog.Posts集合中获得两个副本的帖子。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接