代码之家  ›  专栏  ›  技术社区  ›  Rory

何时使用Microsoft。数据SqlClient。SqlException与系统。数据SqlClient。SqlException?

  •  1
  • Rory  · 技术社区  · 4 年前

    我了解这一点 2019 Microsoft created Microsoft.Data.SqlClient 作为系统的替代品。数据SqlClient。系统数据SqlClient将得到持续支持,但新的开发&所有功能都将在Microsoft中提供。数据SqlClient。这两个库都有一个名为“SqlException”的类。

    假设我使用的是微软。数据SqlClient无处不在,那么相关的异常可能属于Microsoft类型。数据SqlClient。SqlException, 但是 我使用了一堆第三方图书馆,我怎么能确定他们是否会提出 Microsoft.Data.SqlClient.SqlException 或者 System.Data.SqlClient.SqlException ? 这是否意味着在少数情况下,我有微软的catch处理程序。数据SqlClient。SqlException I还应该检查System。数据SqlClient。SqlException?或者有什么聪明的事情发生了,这意味着我只需要想想微软。数据SqlClient。SqlException?

    例如,我有一些旧代码,有点像下面所示,是在我们开始使用Microsoft之前编写的。数据SqlClient。我担心如果我只是简单地把它改成使用微软。数据SqlClient,则会有一些例外,即System。数据SqlClient。SqlException和我的代码将不再注意到它们。

        private static bool HandleSqlExceptionInSomeWay(Exception ex)
        {
            var se = ex as System.Data.SqlClient.SqlException;
    
            if (se != null)
            {
                // ... do something with the SqlException
                return true;
            }
    
            return false;
        }
    

    那么我应该把它改成这样吗,即分别检查不同的类型吗?

        private static bool HandleSqlExceptionInSomeWay(Exception ex)
        {
            // handle old SqlExceptions (e.g. from any old 
            // libraries not using MS package yet)
            var se1 = ex as System.Data.SqlClient.SqlException;
    
            if (se1 != null)
            {
                // ... do something with the SqlException ...
    
                return true;
            }
    
            // handle shiny new SqlExceptions 
            var se2 = ex as Microsoft.Data.SqlClient.SqlException;
    
            if (se2 != null)
            {
                // ... do something with the SqlException ... 
    
                return true;
            }
    
            return false;
        }
    
    2 回复  |  直到 4 年前
        1
  •  12
  •   Panagiotis Kanavos    4 年前

    这两个类不同,但它们确实继承自同一基类, DbException 。不过,这是所有数据库异常的公共类,不会具有两个派生类中的所有属性

    您应该检查您使用的库/NuGet包,并确保使用支持新Microsoft的版本。数据SqlClient库。混淆数据提供者并不有趣,应该尽可能避免。大多数流行的NuGet软件包都使用Microsoft。数据SqlClient已经存在。

    如果不能做到这一点,则选项取决于实际处理数据库异常的方式。是否检查SQL Server特定的属性?

    另一种选择是推迟升级,直到所有NuGet软件包也升级。这两个库都包含在部署过程中需要包含的本机DLL。如果混合库,则必须包含所有本机DLL。

    这可能很痛苦。

    处理异常

    如果两个库都需要使用,则需要分别处理每个异常类型。模式匹配使此操作更容易:

    switch (ex) 
    {
        case  System.Data.SqlClient.SqlException exc:
            HandleOldException(exc);
            return true;
        case Microsoft.Data.SqlClient.SqlException exc:
            HandleNewException(exc);
            return true;
        case DbException exc:
            HandleDbException(exc);
            return true;
        default:
            return false;
    }
    

    映射异常

    另一种选择是将这两个异常类型映射到一个新的自定义类型,该类型包含感兴趣的属性。你必须绘制两个 SqlException 和 SqlError 类。使用“自动映射器”可以更容易地做到这一点:

    var configuration = new MapperConfiguration(cfg => {
        cfg.CreateMap<System.Data.SqlClient.SqlException, MySqlException>();
        cfg.CreateMap<System.Data.SqlClient.SqlError, MySqlError>();
        cfg.CreateMap<Microsoft.Data.SqlClient.SqlException, MySqlException>();
        cfg.CreateMap<Microsoft.Data.SqlClient.SqlError, MySqlError>();
    });
    

    这将允许将异常映射到公共 MySqlException 类型

    var commonExp=mapper.Map<MySqlException>(ex);
    
        2
  •  4
  •   Caius Jard    4 年前

    扩展Richard的回答,这意味着你的尝试/接球最终看起来像:

    try{
      //boom
    } catch(Microsoft.Data.SqlClient.SqlException ex){
      Handler(ex);
    } catch (System.Data.SqlClient.SqlException ex) {
      Handler(ex);
    }
    

    如果你想同时处理这两个问题。。

    Handler是一些可访问的重载(或父类型参数)方法,用于处理每种类型。。虽然不是最漂亮的,但遗憾的是,一个捕获无法捕获N个不同的类型,除非这些类型都有相同的可用父级,可以被捕获(如果需要,还可以检查异常的类型)。。

    编辑完全忘记了 catch when 这对最后一个案例很有用,谢谢@Heinzi

    try{
      //boom
    } catch (DbException ex) 
      when (ex is Microsoft.Data.SqlClient.SqlException || ex is System.Data.SqlClient.SqlException)
    {
      //handle
    }
    
        3
  •  1
  •   Richard Deeming    4 年前

    如果不能确定第三方库是否正在使用 Microsoft 或者 System 图书馆,你需要同时处理这两个问题。没有“神奇的酱汁”可以转化 SqlException 从一个库到 SqlException 从另一个。

    推荐文章