6

I couldn't find good documentation on just exactly what makes Entity Framework decide to look up the correct related object when the foreign key is set.

I'm using lazy loading (but not change tracking) proxies. Setting the foreign key and then getting the navigation property value returns null, even when the related navigation object is already loaded and sitting in the DbContext.

Calling DetectChanges works but seems heavy. Is there any other way to clue in Entity Framework to do fixup?

jnm2
  • 7,960
  • 5
  • 61
  • 99

2 Answers2

7

You're right. DetectChanges is the method that triggers relationship fix-up. If you want relationship fix-up to happen for whatever reason, you call DetectChanges.

But DetectChanges is also called by EF itself when you execute the following methods:

  • DbSet.Add
  • DbSet.Find
  • DbSet.Remove
  • DbSet.Local
  • DbContext.SaveChanges
  • DbSet.Attach
  • DbContext.GetValidationErrors
  • DbContext.Entry
  • DbChangeTracker.Entries
  • Running any LINQ query against a DbSet

(From Lerman & Miller's book DbContext, p. 60).

As you see, almost anything you will do with EF after setting the foreign key value will call DetectChanges, so if you've got other useful stuff to do afterwards, do these things first and save one DetectChanges call.

Gert Arnold
  • 105,341
  • 31
  • 202
  • 291
  • So is there a method that DetectChanges calls that would do fixup without full change detection? – jnm2 Dec 20 '13 at 15:16
  • No, the `ObjectStateManager` only has a private method `AlignChangesInRelationships` that's called in `DetectChanges`. But it it the most efficient way to detect changes first and then fix relationships that are affected by these changes. Not all relationships. – Gert Arnold Dec 20 '13 at 18:46
  • For change notification tracking, I think that EF fixes up the relationships when the change notification occurs. – sjb-sjb Apr 07 '19 at 16:14
1

When using change tracking entities, one of the pair of navigation properties is fixed up when the other navigation is set. For example, say there is a principal entity navigation from Post to Blog and there is a dependent collection property from Blog to Post. If you are using change tracking entities then setting post.Blog = blog will also result in blog.Posts.Add( post). This can be a bit confusing if you are used to doing both post.Blog = blog and then blog.Posts.Add( post) in your code prior to SaveChanges. When you are using DetectChanges this is harmless, but when using change tracking entities you will get two copies of the post in the blog.Posts collection, prior to SaveChanges.

sjb-sjb
  • 1,112
  • 6
  • 14