Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从SQL Server 2008错误代码中识别主键重复?_C#_Sql Server_Entity Framework - Fatal编程技术网

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

C# 如何从SQL Server 2008错误代码中识别主键重复?,c#,sql-server,entity-framework,C#,Sql Server,Entity Framework,我想知道如何从C#中的SQL Server错误代码中识别主键复制错误 例如,我有一个C#表单将数据输入SQL Server数据库,当数据输入时发生错误时,如何从异常中识别错误原因?如果捕获然后查看其编号,则编号2627将意味着违反唯一约束(包括主键) 这是一个一般性错误,无论 数据库被复制。在复制数据库中,错误是 通常会引发,因为未在整个拓扑中正确管理主键 在实体框架的情况下,接受的答案将不起作用,错误最终将不会被捕获。这是一个测试代码,只有entity catch语句会被命中,当然,如果en

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

例如,我有一个C#表单将数据输入SQL Server数据库,当数据输入时发生错误时,如何从异常中识别错误原因?

如果捕获然后查看其编号,则编号
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;
                    }
                }