Как связать индивидуальный номер с исключением

У меня есть код, в который я хочу добавить два исключения; однако, исключения в основном одинаковы, но имеют разные значения. Я хотел бы знать элегантный общий способ определить, какая из этих ошибок произошла.

Я знаю, что могу сделать две попытки перехвата или установить логическое значение для определения успешности запроса. Я также знаю, что это можно сделать за 1 запрос; Тем не менее, я должен быть в состоянии определить, был ли ключ компании неправильным или идентификатор PA был неправильным. Я также знаю, что могу создать собственное исключение и добавить к нему дополнительное поле. К сожалению, я не верю, что какое-либо из них является оптимальным решением, и это беспокоит меня уже довольно давно.

Любая информация о передовой практике будет принята с благодарностью.

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 ответа

Решение

Я бы предложил создать собственное исключение для каждого:

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, Я включил три отдельных конструктора для каждого исключения, потому что это то, что рекомендует Microsoft. Они также рекомендуют сделать сериализацию исключения, если она будет использоваться в определенных сценариях, но ваш пример не требует сериализации.

Вы можете просто указатьParamName когда вы создаете ArgumentException:

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
}

Как насчет определения вашего собственного исключения

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

и использовать его как throw new MyException("Some Message") { MyValue = 666 };

Другие вопросы по тегам