Issue with UPDATE operation on Entity Framework 4 (Pure POCOs)

I have an Entity Framework 4.0 model implemented with pure POCO (without code generation, without self-monitoring objects, just old CLR objects).

Now here is the code I have in my user interface to execute UPDATE:

[HttpPost] public ActionResult UpdatePerson(Person person) { repository.Attach(person); unitOfWork.Commit(); } 

Essentially, I have an action method that accepts a strongly typed Person object, and I need to UPDATE this entity.

Error, but also does not save changes to the database .: (

When I check the EntityState during the "Commit" of my module of work:

 var entities = ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Deleted | EntityState.Modified | EntityState.Unchanged); 

I see my entity with EntityState.Unchanged .

So this explains why it has not survived. The operations "My Search", "Add", "Delete" work fine (they are saved correctly). But UPDATE does not seem to work.

I found several threads saying that I need to manually set the state of the object:

 ctx.ObjectStateManager.ChangeObjectState(person, EntityState.Modified); 

It is right? Where would I put this logic? Expose as an operation on my Unit of work?

Obviously, the problem is that I have change tracking , due to using Pure POCO (without EntityObject derivation, without INotifyPropertyChanging implementation).

But I still have not found a problem with it.

What am I doing wrong?

+4
source share
1 answer

Well, since you don't have change tracking, etc., there should be a way for EF to determine what to do with the attached object when SaveChanges() called. By default, EntityState does not change, so if you want to update, you need to manually set the state.

Another way would be to request Person with this identifier, overwrite the properties with the data that you are retrieving from the controller, and call SaveChanges() . This is actually safer, since you can protect yourself from a situation where a person leaves, when a user edits a web form; but this, obviously, requires an additional reverse transition to the database, which is often less desirable.

In any case, I would have an Update() repository method (more specific than Attach ) that would actually bind the object 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(); } 
+2
source

All Articles