3
votes

I'm developing a web app using the entity framework. I load a list of objects and bind it to a repeater to show a summary of all the items. The user may click an edit icon or a delete icon for each item in the repeater.

Example:

Item 1 | Edit | Delete

Item 2 | Edit | Delete

...

Editing works fine when using a rowversion column for concurrency because the record is loaded and the values for the ID and rowversion column are persisted in hidden form fields. These "original" values are then available to use later when doing the update.

However, if the user clicks Delete for a record, I load the object from the database, call DeleteObject(), then call SaveChanges(). The problem with this is that when I load the record, it gets the latest rowversion value, so any concurrency checking is rendered useless.

How can I ensure that concurrency checking takes place when deleting a record?

3
I don't understand your question. Why would you do any concurrency checking when deleting a record?ZippyV
For example, say you're browsing records looking to delete those that have not been marked as paid. After you bring up the list, another user goes in and marks a record as paid. Based on the information you see (which is now stale), you decide to delete that record. You click the delete button and now a paid record has been removed because it shows as not paid on your screen. In this case, a concurrency check would prevent that from happening.DCNYAM

3 Answers

5
votes

Actually you do not have to load the object from the database, if you want to delete it.

Instead, create an ObjectContext, attach your ObjectToDelete to that context via Attach(), then DeleteObject() and SaveChanges(). Thus you would be able to receive an exception about concurrency.

1
votes

After reading the answer to this question, I decided to use the following approach.

  1. Use hidden form fields to store the ID and rowversion value.
  2. When the user clicks the delete button, load the object from the database. This object contains a rowversion value that may be different than what is stored in the hidden field.
  3. Assign the rowversion value from the hidden field to the appropriate property on the object.
  4. Call the object state manager's AcceptChanges() method for this object. This causes the rowversion value that I had stored to be accepted as the "current" value.
  5. Delete the object and call SaveChanges() on the object context.

Therefore, the original rowversion value I stored is passed to SQL when attempting to delete the record and is compared to the current value in the row. If they do not match, an OptimisticConcurrencyException is raised.

0
votes

A different approach than Andreas H specified would be to use stored procedures to do your deletes. That way you could do concurrency checking and deletion within the stored proc, raising an exception if there is a violation.