Reload() not updating EF entity

2020-07-20 04:06发布

问题:

i like the .NET MVC practice of getting an instantiated class model passed to the controller which already has some of its properties filled in from posted form values. very handy.

[HttpPost]
public ActionResult DoTask(MyModel model)

model arrives with its id and other properties set from the posted form data. however, suppose i want to save the model and then access additional properties that exist only in the database. i need to reload the model at this point.

db.Entry(model).State = EntityState.Modified;
db.SaveChanges();
db.Entry(model).Reload();
//model.relatedModel is empty, as are all other model fields not set by the post

i would expect this to reload the model entirely from the database based on its id. but this does not happen for me. the model properties do not get loaded from the database. they are still empty.

EDIT

i do not understand why db.Entry(model).Reload(); is failing for me. but further reading is beginning to suggest that i should dispose of the dbcontext after performing the save and then reloading the model. is this true?

EDIT

WHOOPS! i have it all wrong. i now see that when i commit the changes db.SaveChanges() i am actually overwriting the entire model, not just the properties that have been set by the MVC controller. i must have the wrong pattern. how do i apply the new values (as passed into my controller) to my database without overwriting the non-modified properties? this is turning into a very nube question, i guess.

CONCLUSION

as it turned out, Reload() DOES update as expected. my problem was that I was overwriting my db row when i called a SaveChanges on my dbcontext using a model that was auto-instantiated by the controller context and passed as a parameter to my controller method. in that case it overwrote both the assigned properties as well as the unassigned ones.

i am now doing a select

model = db.Models.Single(x => x.ID == modelID);

and then updating it using UpdateModel (calling with a prefix to make it work)

UpdateModel(model, "myPrefix");
db.SaveChanges();

回答1:

If you need to update only selected properties you must do it manually:

db.YourEntitySet.Attach(model);
db.Entry(model).Property(m => m.SomeProperty).IsModifed = true;
// other properties here
db.SaveChanges();

After this your reload will work but because you want to reaload the model anyway you can do simply this:

var dbModel = db.YourEntitySet.Single(m => m.Id == model.Id);
dbModel.SomeProperty = model.SomeProperty;
// other properties here
db.SaveChanges();

And you dbModel as the "reloaded" one. You cannot use any authomatic approach like UpdateModel or applying current values because it always overrides everything including values which were not set by your client - EF doesn't know what is valid change.