更新时间:2023-02-20 12:13:44
在DbContext API中解决并发异常的方法将重新加载原始实体:
catch(DbUpdateConcurrencyException ex)
{
//获取失败的条目
var entry = ex.Entries.Single(...);
//用数据库中的值覆盖原始值,但不要
//触摸保存更改的当前值
entry.OriginalValues.SetValues(entry.GetDatabaseValues());
}
您还应该能够使用上述代码,但必须获得 DbContext 实例中的c $ c> ObjectContext 实例(它只是 ObjectContext
的包装
catch(DbUpdateConcurrencyException ex)
{
var objContext =((IObjectContextAdapter)context) .ObjectContext;
//获取失败的条目
var entry = ex.Entries.Single(...);
//现在在ObjectContext上调用刷新
objContext.Refresh(RefreshMode.ClientWins,entry.Entity);
}
您甚至可以尝试:
objContext.Refresh(RefreshMode.ClientWins,ex.Entries.Select(e => e.Entity));
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
The way how to solve concurrency exception in DbContext API reloads original entity:
catch (DbUpdateConcurrencyException ex)
{
// Get failed entry
var entry = ex.Entries.Single(...);
// Overwrite original values with values from database but don't
// touch current values where changes are held
entry.OriginalValues.SetValues(entry.GetDatabaseValues());
}
You should also be able to use the mentioned code but you must get ObjectContext
instance from your DbContext
instance (it is just a wrapper around ObjectContext
).
catch (DbUpdateConcurrencyException ex)
{
var objContext = ((IObjectContextAdapter)context).ObjectContext;
// Get failed entry
var entry = ex.Entries.Single(...);
// Now call refresh on ObjectContext
objContext.Refresh(RefreshMode.ClientWins, entry.Entity);
}
You may even try:
objContext.Refresh(RefreshMode.ClientWins, ex.Entries.Select(e => e.Entity));