Entity framework 我可以自动检测并纠正EF6中的唯一密钥冲突吗?

Entity framework 我可以自动检测并纠正EF6中的唯一密钥冲突吗?,entity-framework,Entity Framework,我有一个非常简单的场景 用户提供输入 签入DB以查看此输入是否已存在 如果有,就用这个 如果没有,创建一个新记录并使用它 输入在数据库中具有唯一的约束 现在的问题是,存在一个竞争条件,这意味着如果两个人同时使用相同的输入进行此操作,那么他们两人都有可能检查数据库,并得到数据库中不存在的答案。然后,它们都将创建一个新记录,第一个记录将能够插入到DB中,但是当第二个记录尝试插入该记录时,它将抛出一个唯一的_密钥冲突错误 是否可以检测此错误,然后“纠正”它,即从第一个进程创建的数据库中获取记录,然后使

我有一个非常简单的场景

  • 用户提供输入
  • 签入DB以查看此输入是否已存在
  • 如果有,就用这个
  • 如果没有,创建一个新记录并使用它
  • 输入在数据库中具有唯一的约束

    现在的问题是,存在一个竞争条件,这意味着如果两个人同时使用相同的输入进行此操作,那么他们两人都有可能检查数据库,并得到数据库中不存在的答案。然后,它们都将创建一个新记录,第一个记录将能够插入到DB中,但是当第二个记录尝试插入该记录时,它将抛出一个唯一的_密钥冲突错误

    是否可以检测此错误,然后“纠正”它,即从第一个进程创建的数据库中获取记录,然后使用该记录


    干杯Mike如果您使用的是类似MS SQL的东西,那么我认为您最好先通过执行以下操作来检查该唯一条目是否存在:

     // See if record exists
     var userInput = context.MyTable.FirstOrDefault(id => id == userInput);
     if (userInput != null)
     {
        userInput = new MyTableEntry();
        // Add entry to DB
        context.MyTable.Add(userInput);
    
        // There is still the slight possibility of a race condition, but
        // SaveChanges() will throw an exception if there is a unique
        // key violation.
        context.SaveChanges();
     }
    

    如果存在密钥冲突,请尝试执行两次(这意味着您尝试两次插入相同的数据)。第二次运行代码时,您几乎可以保证更新现有的db条目。这并不漂亮,但因为数据库可以被多个应用程序访问,所以当您尝试插入重复记录时,实际上必须依靠数据库来告诉您,而在EF中执行此操作的唯一方法是通过“SaveChanges()”

    尝试在EF中使用并发处理:-

    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");
    }
    

    请参见

    这正是我正在做的,但是如果您说有轻微的竞争条件,实际上在我的代码中有很大的竞争条件,因为原始检查和最终保存更改之间可能有很长的时间(可能是几分钟)。我需要的是一些代码,这些代码将检测SaveChanges是否因为唯一密钥冲突而引发异常,然后尝试动态修复它,然后再次调用SaveChanges。这似乎是一个普遍的问题,没有人解决这个问题吗?或者我的想法是错误的?我能找到的关于EF中并发处理的所有示例都表明它在两个进程上工作,这两个进程对数据库中的现有对象进行了更改。我的问题与此不同,因为对象在数据库中还不存在,但有两个单独的进程试图在具有唯一索引的字段中创建具有相同值的对象。并发也可以用来解决这个问题吗?在那种情况下,你能给我举几个例子吗?