【问题标题】:How to swallow ... exception with specific reason如何吞咽……有特定原因的异常
【发布时间】:2014-12-12 18:35:38
【问题描述】:

在这个方法中

    public static void Detach()
    {
        try
        {
            using (var master = new DataContext(@"Data Source=(LocalDB)\MSSQLLocalDB;Initial Catalog=master;Integrated Security=True"))
            {
                master.ExecuteCommand(string.Format("ALTER DATABASE [{0}] SET OFFLINE WITH ROLLBACK IMMEDIATE", DatabaseFile));
                master.ExecuteCommand(string.Format("exec sp_detach_db '{0}'", DatabaseFile));
            }
        }
        catch (Exception e)
        {
           ... // add to log
        }
    }

我可以收到异常

System.Data.SqlClient.SqlException (0x80131904):数据库 'blablabla.mdf' 不存在。提供一个有效的数据库名称。要查看可用的数据库,请使用 sys.databases。

如果在未附加数据库时调用Detach(),则会发生这种情况。

我的问题是:如何仅吞下此特定消息以避免记录它?

文本可能是本地化的,所以这不起作用

if(!(e is SqlException && e.Message.Contains("Supply a valid database name"))) 
    ... // log 

我不确定这个特定案例的错误代码是否唯一(谷歌证明了这一点?)

if(!(e is SqlException && e.Message.Contains("0x80131904"))) 
    ... // log 

当然可以

try { ... } catch {}

但是我没有机会记录一些意外的东西,如果它出现的话可以帮助我解决问题。

【问题讨论】:

    标签: c# exception exception-handling dbml


    【解决方案1】:

    您不想检查 消息 - 您想检查 SQL 特定编号。您可以为此使用 SqlException.Number 属性。

    我会使用:

    // I think this is right, based on
    // http://technet.microsoft.com/en-us/library/cc645936(v=sql.105).aspx
    private const int DatabaseDoesNotExistCode = 15010;
    ...
    catch (SqlException e)
    {
        if (e.Number != DatabaseDoesNotExistCode)
        {
            ...
        }
    }
    

    (我通常不会明白Exception...但这可能是另一回事。)

    【讨论】:

    • 这不起作用 -- 0x80131904 不是“数据库不存在”的代码,它是一个 HRESULT,带有设施 0x13(FACILITY_URT,其中通用运行时是 CLR 的旧名称)和 0x1904是错误代码(来自corerror.h):COR_E_SqlException。也就是说,您刚刚成功检查了 SQL 异常是 SQL 异常。
    • @JeroenMostert:啊哈,看起来Number 属性更合适。
    • 然后你就扔了;重新抛出您不想处理的异常。我会把数字比较变成一个 SWITCH ;) 除非你只有一个。
    • @TomTom:如果有多个代码,这取决于你用它们做什么——如果你在做同样的事情,我会创建一个 List<int>HashSet<int> 来检查它是否是“其中之一”。
    • @TomTom:当抛出 exception 时会发生这种情况 - 我强烈怀疑检查集合中是否存在所花费的时间是一个问题。我会将其视为 less 代码:private static readonly List<int> CodesToSwallow = new List<int> { ... } 然后单行检查...将其与具有大量案例的开关进行比较。
    猜你喜欢
    • 2016-01-21
    • 2013-09-09
    • 1970-01-01
    • 2017-01-26
    • 1970-01-01
    • 2014-08-18
    • 1970-01-01
    • 1970-01-01
    • 2011-04-29
    相关资源
    最近更新 更多