locked
Problem partially updating entities RRS feed

  • Question

  • As confirmed by Daniel Simmons here there is no way in version 1 of the EF to disable concurrency checks on navigation properties. I didn't think it was a big deal at the time but I've just realised it's going to cause me a massive headache.

    Some of my individual entities contain many fields so I've broken the update process up into several stages. This is an asp.net app and I'm using the ObjectDataSource with conflict detection so I get the original values and updated values passed to my business layer method which then attaches the original object to the data context, updates the values from the new value object then calls savechanges.
    Now because of the way my forms are broken up most fields of the entity don't have any data populated. This isn't usually a problem because the nature of change tracking means that only the values that have changed will be written back to the database, the empty fields are empty in both the original and updated entities so these are never marked as changed and the values in the backing store aren't changed.
    Through this method, I'm able to reuse the same domain object and update method for each stage of the update process without problem.

    The problem is though if a concurrency error occurs during an update due to a change in a navigation property I now have no way to resolve the conflict, if I refresh using clientwins the EF seems to treat all the properties in my entity as being changed and will therefore try to write them back to the db, overwriting the changes from differenct sections. Same thing happens if I use storewins, because the entire entity is refreshed applying the changes from the updated entity results in the empty properties being updated.

    If anyone has a good idea how to resolve this problem I'd be really grateful, at the moment the only thing I can think of is to create objects for each update stage and re-write all the update logic, really not a prospect that's appealing.

    Tuesday, August 4, 2009 3:33 PM

Answers

  • Ouch. I don't think there is going to be a real clean way to work around this in EF 3.5 SP1 because there is no way to manually re-set original values and there is no way to set a property as "un-modified". You may have to start over with your context changes: create a new context, requery for the entity, apply the changes to this version of the entity (you can find out which ones are modified from the ObjectStateEntry), Save your changes. Then you can go back to your original context and call "AcceptChanges" on that entity's ObjectStateEntry.

    In EF 4.0 (avialable in Beta form now), while you still will not be able to set a property as un-modified, but you can set original values. In this case, you'd requery the entity (i.e. don't use Refresh), and then re-set the original values of the entity using data from this query.

    Jeff
    This posting is provided "AS IS" with no warranties, and confers no rights.
    • Proposed as answer by Jeff Derstadt - MSFT Thursday, September 24, 2009 3:25 PM
    • Marked as answer by Nazo Thursday, September 24, 2009 3:57 PM
    Thursday, September 24, 2009 3:24 PM

All replies

  • Ouch. I don't think there is going to be a real clean way to work around this in EF 3.5 SP1 because there is no way to manually re-set original values and there is no way to set a property as "un-modified". You may have to start over with your context changes: create a new context, requery for the entity, apply the changes to this version of the entity (you can find out which ones are modified from the ObjectStateEntry), Save your changes. Then you can go back to your original context and call "AcceptChanges" on that entity's ObjectStateEntry.

    In EF 4.0 (avialable in Beta form now), while you still will not be able to set a property as un-modified, but you can set original values. In this case, you'd requery the entity (i.e. don't use Refresh), and then re-set the original values of the entity using data from this query.

    Jeff
    This posting is provided "AS IS" with no warranties, and confers no rights.
    • Proposed as answer by Jeff Derstadt - MSFT Thursday, September 24, 2009 3:25 PM
    • Marked as answer by Nazo Thursday, September 24, 2009 3:57 PM
    Thursday, September 24, 2009 3:24 PM
  • Cheers for the reply, I eventually managed to get around it by using the ObjectStateManager and RelationshipManager to figure out all the scalar and navigation properties that have changed and storing their values. Then when a conflict occurs I can refresh the entity from the store and reapply the changes I've stored.
    It's far from a clean solution but it seems to be working ok and that's the main thing for now.

    I'm definitely looking forward to seeing what the final build of V4.0 can do though.
    Thursday, September 24, 2009 3:57 PM