-1

I have some code where I want to throw two exceptions; however, the exception are basically the same but with different values. I would like to know an elegant generic way to determine which of these errors occurred.

I know I can do two try catches or that I can set a Boolean to determine the success of query. I am also aware that this can be done in 1 query; however, I need to be able to determine if the company key was wrong or if PA id was wrong. I also know that I can create my own exception and add an additional field to it. Unfortunately, I do not believe that any of these are the optimal solution and this has been bothering me for quite some time.

Any information as to best practice would be appreciated.

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"]));
         }
      }
   }
4

3 回答 3

1

How about defining your own exception

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

and use it like throw new MyException("Some Message") { MyValue = 666 };

于 2013-08-19T18:08:28.887 回答
1

I'd suggest creating a custom exception for each:

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) {}
}

You can catch these separately, or you can catch either one as ArgumentException. I've included three separate constructors for each exception because that's what Microsoft recommends. They also recommend making the exception serializable if they'll be used in certain scenarios, but your example doesn't seem to require serialization.

于 2013-08-19T18:20:39.213 回答
1

You could just specify the ParamName when you create the ArgumentException:

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

And then read it when you catch it:

catch (ArgumentException ex)
{
    if (ex.ParamName == "cKey")
        // something
    else if (ex.ParamName == "PAID")
        // something else
    else
        throw; // something else went wrong, rethrow the error
}
于 2013-08-19T18:23:56.623 回答