【问题标题】:Unique column, checking for existing record, best approach唯一列,检查现有记录,最佳方法
【发布时间】:2016-05-27 15:01:39
【问题描述】:

假设我有一个表,其中包含 PK 列、其他一些列,并且其中一个列必须是唯一的。

哪种方法更适合处理添加新记录的可能性,其中唯一键已经存在?

查询数据库,例如

if (!_db.MyTable.Any(mt => mt.UniqueCode == newRecord.UniqueCode))
  _db.MyTable.Add(newRecord);
else //handle response

或者尝试在不检查和处理错误的情况下添加它?例如

try 
}
  _db.MyTable.Add(newRecord);
}
catch (Exception e)
{
  //handle response
}

在第一种方法中,我看到的缺点是它需要 2 次调用 db。 (我离开了_db.SaveChanges()),但我一直觉得最好避免异常。如何?哪一个对性能更好?有没有更好的办法?

【问题讨论】:

  • 我认为在您的应用程序中进行异常处理比第二次往返数据库要好。考虑到对数据库的调用涉及的内容(从 EF 内部到数据库内部和通信的所有内容),异常处理听起来并没有那么糟糕。但我认为应该进行性能测量以证明哪个是最好的。

标签: c# sql .net sql-server entity-framework


【解决方案1】:

第二种方法要好得多,好得多,因为第一种方法不能保证在多线程环境中工作。在检查和插入之间可能会添加一条新记录,从而导致重复记录或异常。

一般情况下,最好让数据库验证数据。即使在应用层可能难以编码的复杂场景中,数据库引擎也能保证唯一性。

【讨论】:

    【解决方案2】:

    通常最好避免部分工作解决方案依赖于“捕获所有异常”的情况。如果可能的话最好避免它,所以通常你应该坚持先查询数据库。

    您可能会遇到不希望事先检查的情况。在这种情况下,您应该首先处理您预期的特定异常,这样您就可以“腾出双手”单独处理任何意外异常。您必须评估是否是这种情况。

    如果是..那么在您的情况下,您可以像这样处理“违反唯一约束”异常:

    try
    {
       _db.MyTable.Add(newRecord);
    }
    catch (SqlException ex)
    {
       if (ex.Number == 2627)
       {
         // Handle unique constraint violation.
       }
       else
       {
         // Handle the remaing SQL errors.
       }
    }
    catch (Exception e)
    {
      // Handle any other non-SQL exceptions
    }
    

    对于具有相应 id 的可能异常列表,您可以运行以下查询:

    SELECT * FROM sys.messages
    WHERE text like '%duplicate%' and text like '%key%' and language_id = 1033
    

    查询来自Unique Key Violation in SQL Server

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-11
      • 1970-01-01
      • 2020-11-12
      • 1970-01-01
      • 2014-10-27
      • 1970-01-01
      • 1970-01-01
      • 2011-09-30
      相关资源
      最近更新 更多