我有一个应用程序,它将大量数据读入内存并批量处理.
我想要的是实体框架DbUpdateConcurrencyException在删除已删除的实体时忽略.
原因是,当一个实体被处理并标记为删除时,它可能已经从数据库中删除.
不经意地删除已经删除的行不是问题,不应该导致错误,我只需要一种方法告诉实体框架:)
例
Db.Entry(itemToRemove).State = EntityState.Deleted;
Db.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
如果itemToRemove已被删除则导致错误.
注意:Db.Configuration.ValidateOnSaveEnabled = false;不会修复此问题,因为另一个线程建议.
Col*_*lin 15
怎么样?
Db.Entry(itemToRemove).State = EntityState.Deleted;
bool saveFailed;
do
{
saveFailed = false;
try
{
Db.SaveChanges();
}
catch(DbUpdateConcurrencyException ex)
{
saveFailed = true;
var entry = ex.Entries.Single();
//The MSDN examples use Single so I think there will be only one
//but if you prefer - do it for all entries
//foreach(var entry in ex.Entries)
//{
if(entry.State == EntityState.Deleted)
//When EF deletes an item its state is set to Detached
//http://msdn.microsoft.com/en-us/data/jj592676.aspx
entry.State = EntityState.Detached;
else
entry.OriginalValues.SetValues(entry.GetDatabaseValues());
//throw; //You may prefer not to resolve when updating
//}
}
} while (saveFailed);
Run Code Online (Sandbox Code Playgroud)
更多信息: 解决乐观并发异常
I posted this question a long time ago but it has recently had some attention so I though I would add the solution I actually use.
//retry up to 5 times
for (var retries = 0; retries < 5; retries++)
{
try
{
Db.SaveChanges();
break;
}
catch (DbUpdateConcurrencyException ex)
{
foreach (var entity in ex.Entries)
{
entity.State = EntityState.Detached;
}
}
}
Run Code Online (Sandbox Code Playgroud)
Things I considered - I did NOT want to use ReloadAsync() or ObjectContext.Refresh as I wanted to ignore items deleted in another process WITHOUT any additional database overhead.
I added in the for loop as a simple protection against infinite loops - not something that should be able to happen, but I'm a belt and braces approach man and not a fan of while(true) if it can be avoided.
No need to a local variable like isDone or saveFailed - simply break if we saved successfully.
No need to cast ex.Entries to a list in order to enumerate it - just because you can write something on one line doesn't make it better.
| 归档时间: |
|
| 查看次数: |
10242 次 |
| 最近记录: |