When handling several potential exceptions during a context.SaveChanges()
one of the exceptions is OptimisticConcurrency
. Microsoft's documentation on this at http://msdn.microsoft.com/en-us/library/bb399228.aspx discusses this for EF 4.x ...
try
{
// Try to save changes, which may cause a conflict.
int num = context.SaveChanges();
Console.WriteLine("No conflicts. " +
num.ToString() + " updates saved.");
}
catch (OptimisticConcurrencyException)
{
// Resolve the concurrency conflict by refreshing the
// object context before re-saving changes.
context.Refresh(RefreshMode.ClientWins, orders);
// Save changes.
context.SaveChanges();
Console.WriteLine("OptimisticConcurrencyException "
+ "handled and changes saved");
}
... but on EF 5.0 (RC), this doesn't seem to work because Refresh()
doesn't exist on my EF5, code-first, DbContext derived context
class.
I do see context.Entry(context.SalesOrderHeaders).Reload();
- but that appears to be a straightup reload-from-db and not a refresh/merge (with policy client wins).
Any ideas how to handle Optimistic concurrency exceptions in EF5? Actually even general pointers on exception handling in SaveChanges() would be nice
Thanks
If your changes are only against the one entity (particular one row, not others tables etc), which is covered by the concurrency mechanism you are allowed to refresh context by disposing the old one and create new one. The thing is when the context is disposed every changed entities and not yet committed are detached from the context and the changes are lost. So be careful about the scope of your unit work!
In the Entity I use extra property for controlling concurrency as follows:
It is maybe not elegant way (and breaks UnitOfWork pattern), but it might be useful in some situations and finally an alternative to the above posts.
The way how to solve concurrency exception in DbContext API reloads original entity:
You should also be able to use the mentioned code but you must get
ObjectContext
instance from yourDbContext
instance (it is just a wrapper aroundObjectContext
).You may even try: