c# - 删除行时如何避免乐观并发异常?

标签 c# optimistic-concurrency ef-core-2.0

我有一个方法可以接收要删除的某些行的 ID。我正在使用这样的代码:

public bool delete(IEnumerable<long> paramIeId)
{
    using(myContext)
    {
        foreach(long iterator in paramIeId)
        {
            nyDbContext.Remove(new MyType(){ID = iterator});
        }
    }
}

它工作正常,因为存在时删除行。但是如果区域 1 或更多行不存在,那么我会得到一个异常,并且没有一行被删除,尽管其中一些存在。

如果我在 T-SQL 中执行此查询我没有问题,数据库会删除现有行并忽略不存在的行,因为最后我想删除它们所以如果另一个进程为我删除了它们,没有问题。

我可以处理刷新 dbContextfrom 数据库的乐观并发异常,但我认为这是可以避免的额外查询。

EF 是否可以像 T-SQL 一样工作?如果我尝试删除不存在的行,请忽略它并删除其余行。

谢谢。

最佳答案

至少目前,在使用分离实体执行删除时,异常似乎是不可避免的。您要么必须使用 try/catch 并处理异常,要么在数据库中查询匹配的 id 并仅删除匹配项 1

异常处理示例

using (myContext)
{
    foreach (long iterator in paramIeId)
    {
        nyDbContext.Remove(new MyType() { ID = iterator });
    }

    try
    {
        nyDbContext.SaveChanges()
    }
    catch(DbUpdateConcurrencyException ex)
    {
        //if you want special handling for double delete
    }
}

样本查询然后删除

请注意,我在循环之前查询了整个类型列表,以避免对每种类型进行单独查询。

using (myContext)
{
    var existingMyTypes = nyDbContext.MyTypes.Where(x => paramIeId.Contains(x.ID));
    foreach (MyType existing in existingMyTypes)
    {
        nyDbContext.Remove(existing);
    }

    nyDbContext.SaveChanges();
}

1 注意:查询然后删除选项会打开一个可能的竞争条件,这可能会触发您尝试的 OptimisticConcurrencyException - 即,如果另一个进程/线程/程序删除您自己进程的读取和删除之间的行。完全处理这种可能性的唯一方法是在 try/catch 中处理异常。

关于c# - 删除行时如何避免乐观并发异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47375761/

相关文章:

c# - EF Core 2.1 启动缓慢

c# - 堆栈跟踪引用不存在的位置

c# - EntityObjects 是否有允许我访问 OldValue 和 NewValue 的 PropertyChanged 事件?

C#委托(delegate)编译器优化

azure - 将 ETag 添加到强类型模型真的是一个坏主意吗?

.net - .NET 的 MongoDB 乐观并发控制

c# - 复合主键部分的 EF 一对多

c# - 在 C# 中取消转义转义的 url

sql-server - 在更新语句中获取最新的行版本/时间戳值 - Sql Server

entity-framework - 如何使用 Entity Framework Core 2.1 查询多对多关系?