如何将自定义数字与异常相关联

时间:2013-08-19 18:01:55

标签: c# .net oracle database-programming

我有一些代码,我想抛出两个例外;但是,异常基本相同但具有不同的值。我想知道一种优雅的通用方法来确定发生了哪些错误。

我知道我可以做两次尝试捕获,或者我可以设置一个布尔值来确定查询是否成功。我也知道这可以在1个查询中完成;但是,我需要能够确定公司密钥是否错误或PA id是否错误。我也知道我可以创建自己的异常并为其添加一个额外的字段。不幸的是,我不相信其中任何一个都是最佳解决方案,这已经困扰了我很长一段时间。

任何有关最佳做法的信息都将受到赞赏。

using (var ora = new OracleConnection(Data.ConnectionString))
{
    String sqlGetCompanyId = "SELECT COMPANY_ID FROM companies WHERE key = :key";
    String sqlValidateDelete = "select * from pa where PA_ID = :paid AND COMPANY_ID = :cid";

    ora.Open();
    int CompanyId = 0;

    using (var Command = ora.CreateCommand())
    {
        Command.CommandText = sqlGetCompanyId;
        Command.Parameters.Add(":key", OracleDbType.Varchar2).Value = cKey;

        using (var reader = Command.ExecuteReader(CommandBehavior.SingleRow))
        {
            if (reader.Read())
               CompanyId = unchecked((int)((long)reader["COMPANY_ID"]));
            else
               throw new ArgumentException("Invalid Company Key");
        }
     }

     using (var Command = ora.CreateCommand())
     {
         Command.CommandText = sqlValidateDelete;
         Command.Parameters.Add(":cid", OracleDbType.Int32).Value = CompanyId;
         Command.Parameters.Add(":paid", OracleDbType.Int32).Value = PAID;

         using (var reader = Command.ExecuteReader(CommandBehavior.SingleRow))
         {
             if (!reader.Read())
                throw new ArgumentException("Price Agreement Id for this company does not exist");
             rv = unchecked((int)((long)reader["ROW_VERSION"]));
         }
      }
   }

3 个答案:

答案 0 :(得分:1)

如何定义自己的异常

public class MyException : ArgumentException
{
    public MyException(string s) : base(s)
    {
    }
    public int MyValue { set; get; }
}

并像throw new MyException("Some Message") { MyValue = 666 };

一样使用它

答案 1 :(得分:1)

我建议为每个人创建一个自定义例外:

public class InvalidCompanyKeyException : ArgumentException {
   public InvalidCompanyKeyException() : base() {}
   public InvalidCompanyKeyException(string message) : base(message) {}
   public InvalidCompanyKeyException(string message, Exception inner) : base(message, inner) {}
}

public class PriceAgreementIdNotFoundException : ArgumentException {
   public PriceAgreementIdNotFoundException() : base() {}
   public PriceAgreementIdNotFoundException(string message) : base(message) {}
   public PriceAgreementIdNotFoundException(string message, Exception inner) : base(message, inner) {}
}

您可以单独捕捉这些内容,也可以将其中一个捕获为ArgumentException。我为每个例外都包含了三个独立的构造函数,因为that's what Microsoft recommends。如果在某些情况下使用异常,他们还建议将异常序列化,但您的示例似乎并不需要序列化。

答案 2 :(得分:1)

创建ArgumentException时,您可以specify the ParamName

throw new ArgumentException("Invalid Company Key", "cKey");
...
throw new ArgumentException("Price Agreement Id for this company does not exist",
                            "PAID");

然后在你抓住它时阅读它:

catch (ArgumentException ex)
{
    if (ex.ParamName == "cKey")
        // something
    else if (ex.ParamName == "PAID")
        // something else
    else
        throw; // something else went wrong, rethrow the error
}