如何使用 EF6 和 SQL Server 捕获 UniqueKey Violation 异常?

How can I catch UniqueKey Violation exceptions with EF6 and SQL Server?(如何使用 EF6 和 SQL Server 捕获 UniqueKey Violation 异常?)
本文介绍了如何使用 EF6 和 SQL Server 捕获 UniqueKey Violation 异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的一个表有一个唯一键,当我尝试插入重复记录时,它会按预期抛出异常.但是我需要将唯一键异常与其他异常区分开来,这样我就可以自定义违反唯一键约束的错误消息.

One of my tables have a unique key and when I try to insert a duplicate record it throws an exception as expected. But I need to distinguish unique key exceptions from others, so that I can customize the error message for unique key constraint violations.

我在网上找到的所有解决方案都建议将 ex.InnerException 转换为 System.Data.SqlClient.SqlException 并检查 if Number 属性等于 2601 或 2627 如下:

All the solutions I've found online suggests to cast ex.InnerException to System.Data.SqlClient.SqlException and check the if Number property is equal to 2601 or 2627 as follows:

try
{
    _context.SaveChanges();
}
catch (Exception ex)
{
    var sqlException = ex.InnerException as System.Data.SqlClient.SqlException;

    if (sqlException.Number == 2601 || sqlException.Number == 2627)
    {
        ErrorMessage = "Cannot insert duplicate values.";
    }
    else
    {
        ErrorMessage = "Error while saving data.";
    }
}

但问题是,将 ex.InnerException 转换为 System.Data.SqlClient.SqlException 会导致无效的转换错误,因为 ex.InnerExceptionSystem.Data.Entity.Core.UpdateException 的实际类型,而不是 System.Data.SqlClient.SqlException.

But the problem is, casting ex.InnerException to System.Data.SqlClient.SqlException causes invalid cast error since ex.InnerException is actually type of System.Data.Entity.Core.UpdateException, not System.Data.SqlClient.SqlException.

上面的代码有什么问题?如何捕获违反唯一键约束的行为?

What is the problem with the code above? How can I catch Unique Key Constraint violations?

推荐答案

使用 EF6 和 DbContext API(用于 SQL Server),我目前正在使用这段代码:

With EF6 and the DbContext API (for SQL Server), I'm currently using this piece of code:

try
{
  // Some DB access
}
catch (Exception ex)
{
  HandleException(ex);
}

public virtual void HandleException(Exception exception)
{
  if (exception is DbUpdateConcurrencyException concurrencyEx)
  {
    // A custom exception of yours for concurrency issues
    throw new ConcurrencyException();
  }
  else if (exception is DbUpdateException dbUpdateEx)
  {
    if (dbUpdateEx.InnerException != null
            && dbUpdateEx.InnerException.InnerException != null)
    {
      if (dbUpdateEx.InnerException.InnerException is SqlException sqlException)
      {
        switch (sqlException.Number)
        {
          case 2627:  // Unique constraint error
          case 547:   // Constraint check violation
          case 2601:  // Duplicated key row error
                      // Constraint violation exception
            // A custom exception of yours for concurrency issues
            throw new ConcurrencyException();
          default:
            // A custom exception of yours for other DB issues
            throw new DatabaseAccessException(
              dbUpdateEx.Message, dbUpdateEx.InnerException);
        }
      }

      throw new DatabaseAccessException(dbUpdateEx.Message, dbUpdateEx.InnerException);
    }
  }

  // If we're here then no exception has been thrown
  // So add another piece of code below for other exceptions not yet handled...
}

正如您提到的 UpdateException,我假设您使用的是 ObjectContext API,但它应该是相似的.

As you mentioned UpdateException, I'm assuming you're using the ObjectContext API, but it should be similar.

这篇关于如何使用 EF6 和 SQL Server 捕获 UniqueKey Violation 异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
Programmatically show the desktop(以编程方式显示桌面)
c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)