如何从SQL Server 2008错误代码中识别主键重复?

我想知道如何从C#中的SQL Server错误代码中识别主键重复错误。

作为一个例子,我有一个C#表单将数据输入到SQL Server数据库中,当数据输入时发生错误时,如何从exception中识别出错误的原因?

如果捕获SqlException然后查看其编号,则数字2627将表示违反唯一约束(包括主键)。

 try { // insertion code } catch (SqlException ex) { if (ex.Number == 2627) { //Violation of primary key. Handle Exception } else throw; } 

MSSQL_ENG002627

无论是否复制数据库,这都是可以引发的一般错误。 在复制数据库中, 通常会引发错误, 因为未在拓扑中正确管理主键

这是一个老线程,但我想值得注意的是,自从C#6你可以:

 try { await command.ExecuteNonQueryAsync(cancellation); } catch (SqlException ex) when (ex.Number == 2627) { // Handle unique key violation } 

使用C#7和包装exception(如Entity Framework Core):

 try { await _context.SaveChangesAsync(cancellation); } catch (DbUpdateException ex) when ((ex.InnerException as SqlException)?.Number == 2627) { // Handle unique key violation } 

与接受的答案相比,这种方法的最大优点是:

如果错误号等于2627,因此它不是唯一的密钥违规,则不会捕获exception。

没有exceptionfilter( when ),你最好记住重新抛出exception,以防你无法处理。 理想情况下不要忘记使用ExceptionDispatchInfo以便原始堆栈不会丢失。

在entity framework的情况下,接受的答案将不起作用,错误将最终没有被捕获。 这是一个测试代码,如果删除了实体语句,则只会触发实体catch语句,或者当然是通用exception:

 try { db.InsertProcedureCall(id); } catch (SqlException e0) { // Won't catch } catch (EntityCommandExecutionException e1) { // Will catch var se = e1.InnerException as SqlException; var code = se.Number; } catch (Exception e2) { // if the Entity catch is removed, this will work too var se = e2.InnerException as SqlException; var code = se.Number; }