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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15217711/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 14:31:01  来源:igfitidea点击:

How to Identify the primary key duplication from a SQL Server 2008 error code?

c#sql-serverentity-framework

提问by Roshan

I want to know how we identify the primary key duplication error from SQL Server error code in C#.

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

As a example, I have a C# form to enter data into a SQL Server database, when an error occurs while data entry, how can I identify the reason for the error from the exception?

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

采纳答案by Habib

If you catch SqlExceptionthen see its number, the number 2627would mean violation of unique constraint (including primary key).

如果您捕获SqlException然后查看其编号,则该编号2627意味着违反了唯一约束(包括主键)。

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

MSSQL_ENG002627

MSSQL_ENG002627

This is a general error that can be raised regardless of whether a database is replicated. In replicated databases, the error is typically raised because primary keys have not been managed appropriatelyacross the topology.

这是一个无论是否复制数据库都可能引发的一般错误。在复制数据库中,通常会因为主键没有在拓扑中进行适当管理而引发错误 。

回答by usefulBee

In case of Entity Framework, the accepted answer won't work and the error will end up not being caught. Here is a test code, only the entity catch statement will be hit or of course the generic exception if entity statement removed:

在实体框架的情况下,接受的答案将不起作用,错误最终不会被捕获。这是一个测试代码,只有实体 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;
}

回答by Bruno Garcia

This is an old thread but I guess it's worth noting that since C#6 you can:

这是一个旧线程,但我想值得注意的是,从 C#6 开始,您可以:

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

And with C#7 and a wrapping exception (like Entity Framework Core):

使用 C#7 和一个包装异常(如 Entity Framework Core):

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

The biggest advantage of this approach in comparison with the accepted answer is:

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

In case the error number is notequal to 2627 and hence, it's not a unique key violation, the exception is not caught.

如果错误号等于 2627,因此它不是唯一键违规,则不会捕获异常。

Without the exception filter (when) you'd better remember re-throwing that exception in case you can't handle it. And ideally not to forget to use ExceptionDispatchInfoso that the original stack is not lost.

如果没有异常过滤器 ( when),您最好记住重新抛出该异常,以防您无法处理它。理想情况下不要忘记使用,ExceptionDispatchInfo以免丢失原始堆栈。

回答by Tauqeer

Working code for filter only duplicate primary key voilation exception

过滤器仅重复主键失效异常的工作代码

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;
                    }
                }

Note fine detial :- ex.InnerException.InnerException not ex.InnerException

注意细节:- ex.InnerException.InnerException 不是 ex.InnerException