1

I'm migrating my EF6 MVC project from ObjectContext to DbContext with lazy loading.

With ObjectContext, I could do the following:

// Create a new user:
 User u = new User();
 u.LineManagerID = 42;   // Set foreign key

 db.Users.Add(u);
 db.SaveChanges();

// get property of related entity as set above by foreign key 
 User lm = u.LineManager;

With DbContext, u.LineManager is null even the the new entity is saved correctly and I suspect if I did another call to the database it would be fine.

Lazy loading and dynamic proxies are both enabled.

Why doesn't the new entity refresh properly?

Please help! I can see this migration is going to be lot harder than I thought...!

EDIT - I should add that I am using db-first code generation

rwalter
  • 881
  • 1
  • 7
  • 17
  • possible duplicate of [Entity Framework: I set the foreign key, SaveChanges then access the navigation property, but it doesn't load the related entity. Why not?](http://stackoverflow.com/questions/15552891/entity-framework-i-set-the-foreign-key-savechanges-then-access-the-navigation) – Colin Nov 14 '13 at 17:24
  • I think you have to change to db.Users.Attached(user); then you have to tell it that you are updating something. It would be something like db.Users.Attached(user); db.Entry(user).State = EntityState.Modified; In addition, I don't believe that you have to manually tell it which id to update. As long as you have a reference to that manager on your view. For example, if you have something like @html.EditorFor(model => model.Manager.Name) to capture the manager name, it should update the proper column. Hope I make sensse. – Josiane Ferice Nov 14 '13 at 17:37

1 Answers1

9

You have to make the LineManager property virtual to be overridable by the lazy loading proxy. (which it already is thanks to the code generation)

When you are creating the object directly with new you are unfortunately just creating a plain object - not the proxy one with all the lazy loading features. To get those, you need to use a factory method to create your object:

User u = db.Users.Create();

I did some experimenting with navigation properties and foreign keys that I documented in a blog post.

Anders Abel
  • 64,109
  • 15
  • 143
  • 213
  • Sorry Anders - just made some edits to my question which may change your answer. – rwalter Nov 14 '13 at 17:22
  • Also I'm using db-first, so I shouldn't be adding `virtual` or anything else to the code that's auto-generated. – rwalter Nov 14 '13 at 17:23
  • Well, that's right - I just updated my answer with a solution to the real problem - didn't see it first. – Anders Abel Nov 14 '13 at 17:25
  • Excellent, clear explanation of the `new` thing. I can see your blog post is very helpful HOWEVER if anyone knows of a blog post that can help me migrate to DbContext from ObjectContext, that would be tremendous. I've had a google but couldn't find anything comprehensive. – rwalter Nov 14 '13 at 17:30
  • Does this also mean that I can no longer populate the entity fields on construction e.g. `User u = new User() { Name="Joe" }`? – rwalter Nov 14 '13 at 17:35
  • No, unfortunately you can't when using the factory method. The EF proxies are quite magic - but sometimes the magic fails to conceal what's going on underneath. – Anders Abel Nov 14 '13 at 17:38
  • I've concealed the Create method inside my generic repository class in order to let me new up entities and keep the magic http://stackoverflow.com/a/16811976/150342 – Colin Nov 14 '13 at 18:29