如何使用我的Entity Framework代码忽略DbUpdateConcurrencyException?

Pur*_*ome 10 .net entity-framework entity-framework-ctp5

有什么方法可以告诉EF不要担心a DELETE或者UPDATE做或不做的行数?

我正在尝试从数据库中删除一行,但由于该行不存在,EF会抛出异常:DbUpdateConcurrencyException..说0行受到影响.这是对的 - >没有删除任何行.但那完全没问题......因为没有数据.

我真的不想对数据库进行往返查看该行是否存在..如果是这样的话...然后尝试删除它.

如果我尝试吞下一个try / catch块中的异常,那么当我尝试SaveChanges()...这是坏事时,要删除的其余项目不会被发送到数据库.

例如.

Delete(new Foo(1));
Delete(new Foo(2));
Delete(new Foo(3));
SaveChanges(); // <-- Throws the exception.

// DB Trace : DELETE FROM Foo WHERE Id = 1;
Run Code Online (Sandbox Code Playgroud)

并且那就是..没有迹象显示记录2或3试图被删除..因为异常停止一切:(

有任何想法吗?

UPDATE

Delete工作怎么样?这是代码......(简化和强类型)

public void Delete(Foo foo)
{
    if (foo == null)
    {
        throw new ArgumentNullException("foo");
    }

    Foo attachedEntity = Context.Set<Foo>().Local.FirstOrDefault(x => x.Id > 0);

    if (attachedEntity != null)
    {
        // Entity already in object graph - remove entity.
        Context.Set<Foo>().Remove(attachedEntity);
    }
    else
    {
        // Entity not in object graph, attach and set EntityState to Deleted.
        Context.Entry(foo).State = EntityState.Deleted;
    }
}
Run Code Online (Sandbox Code Playgroud)

Lad*_*nka 2

我认为 EF 的行为是正确的 - 只是您必须仅对 DB 中存在的对象执行命令。它不适用于这样的场景:“我会尝试一下,我们会看到......”。如果您不能确定该对象存在于数据库中并且您不想进行往返(我认为这是最好的主意,因为删除分离的对象可能会有其他几个陷阱,特别是如果对象参与独立关联),您应该使用DbContext.Database.SqlCommand并运行存储过程。

这里DbUpdateConcurrencyException描述了正确的处理方法=> 在每个异常之后,您应该解决冲突(在您的情况下,这意味着从 DbContext 中删除有问题的实体)并再次执行。SaveChanges

  • 我不同意这个答案,EF的行为是不正确的。可以这样想 - 用户 A 执行 SELECT,存在。用户B确实存在,存在。用户A删除,成功。用户B删除,异常失败。在这两种情况下,结果应该是相同的 - 我们正在删除记录。当然,存在冲突,但结果是相同的 - 删除了行。没有什么需要解决的。“首先检查它是否存在”是行不通的——这是一个竞争条件。无法在所有情况下锁定读取,在我们的示例中,我们使用 MySQL 集群 - 无读取锁定。 (5认同)