C# 如何从SQL Server 2008错误代码中识别主键重复?
我想知道如何从C#中的SQL Server错误代码中识别主键复制错误 例如,我有一个C#表单将数据输入SQL Server数据库,当数据输入时发生错误时,如何从异常中识别错误原因?如果捕获然后查看其编号,则编号C# 如何从SQL Server 2008错误代码中识别主键重复?,c#,sql-server,entity-framework,C#,Sql Server,Entity Framework,我想知道如何从C#中的SQL Server错误代码中识别主键复制错误 例如,我有一个C#表单将数据输入SQL Server数据库,当数据输入时发生错误时,如何从异常中识别错误原因?如果捕获然后查看其编号,则编号2627将意味着违反唯一约束(包括主键) 这是一个一般性错误,无论 数据库被复制。在复制数据库中,错误是 通常会引发,因为未在整个拓扑中正确管理主键 在实体框架的情况下,接受的答案将不起作用,错误最终将不会被捕获。这是一个测试代码,只有entity catch语句会被命中,当然,如果en
2627
将意味着违反唯一约束(包括主键)
这是一个一般性错误,无论
数据库被复制。在复制数据库中,错误是
通常会引发,因为未在整个拓扑中正确管理主键
在实体框架的情况下,接受的答案将不起作用,错误最终将不会被捕获。这是一个测试代码,只有entity catch语句会被命中,当然,如果entity语句被删除,则会出现泛型异常:
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;
}
这是一条古老的线索,但我想值得注意的是,由于C#6,您可以:
try
{
await command.ExecuteNonQueryAsync(cancellation);
}
catch (SqlException ex) when (ex.Number == 2627)
{
// Handle unique key violation
}
对于C#7和包装异常(如实体框架核心):
与公认的答案相比,这种方法的最大优点是:
如果错误号不等于2627,因此不是唯一的密钥冲突,则不会捕获异常
如果没有异常过滤器(
当
时),最好记住重新抛出该异常,以防无法处理它。理想情况下,不要忘记使用异常DispatchInfo
,这样原始堆栈就不会丢失。仅用于筛选器的工作代码重复主键voilation异常
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 not ex.InnerException@Roshan您必须使用
SqlException
,而不是System.Exception
,如果您同时使用这两种方法,请确保更具体的异常的catch块位于不太具体的异常之上(在这种情况下,SqlException
的catch块必须位于Exception
的catch块之上)。我相信2601也可以是唯一的索引,因此值得注意的是,您可以使用异常筛选,因此当(ex.Number==2627){//do something}
try
{
await _context.SaveChangesAsync(cancellation);
}
catch (DbUpdateException ex)
when ((ex.InnerException as SqlException)?.Number == 2627)
{
// Handle unique key violation
}
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;
}
}