我想知道如何识别C#中SQL Server错误代码的主键重复错误。
作为一个例子,我有一个C#表单将数据输入到SQL Server数据库中,当数据输入时发生错误时,如何从异常中识别出错误的原因?
答案 0 :(得分:51)
如果您抓住SqlException然后查看其编号,则数字2627
将表示违反唯一约束(包括主键)。
try
{
// insertion code
}
catch (SqlException ex)
{
if (ex.Number == 2627)
{
//Violation of primary key. Handle Exception
}
else throw;
}
这是一个可以提出的一般错误,无论是否a 数据库被复制。在复制的数据库中,错误是 通常会引发,因为拓扑中没有正确管理主键。
答案 1 :(得分:4)
这是一个老线程,但我想值得注意的是,因为C#6你可以:
try
{
await command.ExecuteNonQueryAsync(cancellation);
}
catch (SqlException ex) when (ex.Number == 2627)
{
// Handle unique key violation
}
使用C#7和包装异常(如Entity Framework Core):
try
{
await _context.SaveChangesAsync(cancellation);
}
catch (DbUpdateException ex)
when ((ex.InnerException as SqlException)?.Number == 2627)
{
// Handle unique key violation
}
与接受的答案相比,这种方法的最大优点是:
如果错误编号不等于2627,因此,它不是唯一的密钥违规,则不会捕获异常。
如果没有例外过滤器(when
),您最好记住重新抛出该异常,以防您无法处理。理想情况下,不要忘记使用ExceptionDispatchInfo
,以免原始堆栈丢失。
答案 2 :(得分:0)
在实体框架的情况下,接受的答案将不起作用,错误将最终没有被捕获。这是一个测试代码,如果实体语句被删除,则只会触发实体catch语句,或者当然是通用异常:
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;
}
答案 3 :(得分:0)
仅用于过滤器的工作代码重复的主键冲突异常
using System.Data.Entity.Infrastructure;
using System.Data.SqlClient;
.........
try{
abc...
}
catch (DbUpdateException ex)
{
if (ex.InnerException.InnerException is SqlException sqlEx && sqlEx.Number == 2601)
{
return ex.ToString();
}
else
{
throw;
}
}
注意细节:-ex.InnerException.InnerException而不是ex.InnerException