5
votes

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?

2

2 Answers

4
votes

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.

0
votes

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.