I have an Entity Framework 4.0 model implemented with pure POCO's (no code generation, no self-tracking entities, just plain old CLR objects).
Now, here is some code i have in my UI to perform an UPDATE:
[HttpPost]
public ActionResult UpdatePerson(Person person)
{
repository.Attach(person);
unitOfWork.Commit();
}
Essentially, i have an Action Method which accepts a strongly-typed Person object, and i need to UPDATE this entity.
Doesn't error, but also doesn't persist the changes to the DB either. :(
When i inspect the EntityState during the "Commit" of my Unit of Work:
var entities = ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Deleted | EntityState.Modified | EntityState.Unchanged);
I see my entity, with EntityState.Unchanged.
So that explains why it has not been persisted. My Find,Add,Delete operations are working fine (persisting correctly). But UPDATE doesn't seem to work.
I've found some threads saying i need to manually set the object state:
ctx.ObjectStateManager.ChangeObjectState(person, EntityState.Modified);
Is that correct? Where would i put this logic? Expose as an operation on my Unit of Work?
Obviously the issue is i have no change tracking whatsoever, due to the use of Pure POCO's (no EntityObject derivation, no INotifyPropertyChanging implementation).
But开发者_如何学编程 i haven't found an issue with it until now.
What am i doing wrong?
Well, since you don't have any change tracking, etc., there should be a way for EF to determine what to do with the attached entity when SaveChanges()
is called. By default, the EntityState is Unchanged, so if you want to Update, you have to manually set the state.
Another way would be to query for the Person
with this Id, rewrite the properties with the data you fetch from the controller, and call SaveChanges()
. This is a safer way actually, since you can guard yourself from a situation where the Person gets deleted while the user is editing the webform; but this obviously requires an extra roundtrip to the DB, which is often less desirable.
In any case, I would have a repository Update()
method (more specific than Attach
), that would actually attach the entity and change the EntityState
to Modified
. And you still have relatively clean code in your Action:
public ActionResult UpdatePerson(Person person)
{
repository.Update(person);
unitOfWork.Commit();
}
精彩评论