独特的专栏,检查现有记录,最佳方法

时间:2016-02-16 11:01:43

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

假设我有一个包含PK列的表,一些其他列,以及一个必须唯一的表。

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

查询数据库,例如

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

或尝试添加它而不检查并处理错误? e.g。

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

在第一种方法中,我看到的缺点是需要2次调用db。 (我离开了_db.SaveChanges()),但我总觉得最好避免异常。如何?哪一个会更好的表现?还有更好的方法吗?

2 个答案:

答案 0 :(得分:3)

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

通常,最好让数据库尽可能验证数据。即使在可能难以在应用程序层编码的复杂场景中,数据库引擎也能保证唯一性。

答案 1 :(得分:1)

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

您可以提出以下情况,其中事先检查不是首选。在这种情况下,您应该首先处理您预期的特定异常,这样您就可以免费使用"单独处理任何意外的例外。你必须评估这是否是这种情况。

如果是..那么在您的情况下,您可以处理"唯一约束违规"像这样的例外:

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