我可以自动检测并纠正EF6中的唯一密钥违规吗?

时间:2014-08-29 17:23:47

标签: entity-framework

我有一个非常简单的场景。

  1. 用户提供输入。
  2. 检入数据库以查看此输入是否已存在。
  3. 如果是,请使用它。
  4. 如果没有,请创建新记录并改为使用。
  5. 输入在数据库中有唯一约束。

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

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

    干杯迈克

2 个答案:

答案 0 :(得分:0)

如果您正在使用类似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()”< / p>

答案 1 :(得分:0)

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

请参阅http://msdn.microsoft.com/en-us/library/vstudio/bb738618(v=vs.100).aspx