Как создать собственное исключение в С#

Я хочу создать собственное исключение в приложении Windows Form. Я пытаюсь добавить некоторые данные в базу данных.

код:

try
{
    string insertData = string.Format("INSERT INTO " + constants.PIZZABROADCASTTABLE + 
      " VALUES(@starttime,@endtime,@lastupdatetime,@applicationname)");
    sqlCommand = new SqlCommand(insertData, databaseConnectivity.connection);
    sqlCommand.Parameters.AddWithValue("@starttime", broadcastStartDateTime);
    sqlCommand.Parameters.AddWithValue("@endtime", broadcastEndDateTime);
    sqlCommand.Parameters.AddWithValue("@lastuptime", currentDateTime);
    sqlCommand.Parameters.AddWithValue("@applicationname", txtApplicationName.Text);
    sqlCommand.ExecuteNonQuery();
}
catch (DataBaseException ex)
{
    MessageBox.Show(ex.Message);
}

Здесь я создал свое собственное исключение. Здесь я дал скалярную переменную @lastuptime вместо @lastupdatetime для захвата исключения SqlException.

Вот мой класс DatabaseException.

class DataBaseException : Exception
{
    public DataBaseException(string Message)
        : base(Message)
    {

    }
    public DataBaseException(string message, Exception innerException)
        : base(message, innerException)
    {
    }
}

Здесь при запуске программы она показывает ошибку на

 sqlCommand.ExecuteQuery();

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

Может кто-нибудь помочь мне? Заранее спасибо.


person bharathi    schedule 16.09.2011    source источник
comment
Вы также должны пометить свое исключение как [Serializable] и добавить еще два конструктора (конструктор без аргументов для сериализации и конструктор с SerializationInfo и StreamingContext в качестве аргументов для пользовательской сериализации).   -  person Daniel    schedule 16.09.2011


Ответы (5)


Вам нужно создать собственное исключение, чтобы оно могло быть перехвачено вызывающим методом. В вашем коде программа будет генерировать исключение из БД, а не ваше пользовательское исключение.

void UpdateDatabase()
{
//...
        try 
            { 

            } 
               // Your checks to identify - type of exception
               // ...
              // .net exception
              // Throw your custom exception in the appropriate block - 
              // throw new DatabaseException();
            catch (OutOfMemoryException ex1) 
            { 

            }
            catch (InvalidDataException ex2) 
            { 

            }
            // Generic exception
            catch (Exception ex3) 
            { 
                // throw new DatabaseException();
            } 
//....
}

// Method calling UpdateDatabase need to handle Custom exception
void CallUpdateDatabase()
{
 try
  {
    UpdateDatabase();
  }
  catch(DatabaseException dbEx)
  {
    // Handle your custom exception
  }
}
person Sandeep G B    schedule 16.09.2011
comment
Вы можете захотеть предоставить конструктор, который принимает объект исключения, чтобы вы могли сохранить внутреннее исключение. - person Ryan Stecker; 16.09.2011
comment
если вы знаете типы исключений, которые нужно перехватывать, вместо того, чтобы проверять тип в операторе if, перехватывайте их конкретно (т.е. catch (DatabaseException de){} catch(SQLiteException) {} catch (NullRefer.. - person William Melani; 16.09.2011

Ни одно из свойств и методов SqlCommand не создает созданное вами DatabaseException. Поэтому ваш улов никогда не сработает.

Тот факт, что вы создали и назвали свое исключение DatabaseException, не означает, что весь код «базы данных» теперь будет вызывать ваше исключение. Когда SqlCommand был написан, он был написан для создания очень определенного набора исключений. Список исключений SqlCommand и его методы можно найти в MSDN.

Дайте мне знать, если мой ответ не имеет для вас смысла.

person Esteban Araya    schedule 16.09.2011

ваше собственное исключение в порядке, но Sql.ExecuteQuery вызовет SqlException, вы можете сделать что-то вроде этого:

void CallDatabase( /* your parameters */)
{
    try
    {
        string insertData = string.Format("INSERT INTO " + constants.PIZZABROADCASTTABLE + " VALUES(@starttime,@endtime,@lastupdatetime,@applicationname)");
        sqlCommand = new SqlCommand(insertData, databaseConnectivity.connection);
        sqlCommand.Parameters.AddWithValue("@starttime", broadcastStartDateTime);
        sqlCommand.Parameters.AddWithValue("@endtime", broadcastEndDateTime);
        sqlCommand.Parameters.AddWithValue("@lastuptime", currentDateTime);
        sqlCommand.Parameters.AddWithValue("@applicationname", txtApplicationName.Text);
        sqlCommand.ExecuteNonQuery();

    }
    catch (SqlException ex)
    {
        throw new DataBaseException("Database error", ex);
    }
}

/* somewhere in your code */
try
{
   CallDatabase(...);
}
catch (DataBaseException ex)
{
    MessageBox.Show(ex.Message);
}
person Random Dev    schedule 16.09.2011

Вот как я бы написал эту процедуру (более или менее). Убедитесь, что вы закрываете соединение с БД и используете конструкцию using, чтобы освободить объект sqlCommand:

 try
    {
        string insertData = string.Format("INSERT INTO " + constants.PIZZABROADCASTTABLE + " VALUES(@starttime,@endtime,@lastupdatetime,@applicationname)");
        using (sqlCommand = new SqlCommand(insertData, databaseConnectivity.connection))
        {
            sqlCommand.Parameters.AddWithValue("@starttime", broadcastStartDateTime);
            sqlCommand.Parameters.AddWithValue("@endtime", broadcastEndDateTime);
            sqlCommand.Parameters.AddWithValue("@lastuptime", currentDateTime);
            sqlCommand.Parameters.AddWithValue("@applicationname", txtApplicationName.Text);

            sqlCommand.ExecuteNonQuery();
        }
    }
    catch (Exception ex)
    {
        string s = "Failed to insert into table " + constants.PIZZABROADCASTTABLE + "Database Error! " + Environment.NewLine + "Details: " + ex.ToString();
        MessageBox.Show(s, MessageBoxButtons.OK, MessageBoxIcons.Error);
        // Or
        //throw new DatabaseException(s, ex);
    }
    finally
    {
        if (databaseConnectivity != null && databaseConnectivity.connection != null) 
            databaseConnectivity.connection.Close();
        else
            MessageBox.Show("No database connectivity!", "Error", MessageBoxButtons.OK, MessageBoxIcons.Error); 
    }
person tzup    schedule 16.09.2011

С Throw Class больше информации здесь.

http://msdn.microsoft.com/en-us/library/system.activities.statements.throw.aspx

С Уважением.

person Carmelo La Monica    schedule 16.09.2011