Правильное использование конструкции try/catch пункт по исполнению базе


Когда заявление на возврат БД значение null, я ловила его таким способом:

private int GetLastRoundNumber(int period)
{
    int id;
    try
    {
        using (NpgsqlConnection con = new NpgsqlConnection(_entwConnection))
        {
            con.Open();
            using (NpgsqlCommand cmd = new NpgsqlCommand())
            {
                cmd.Connection = con;
                cmd.CommandText = "SELECT roundNumberId FROM race.folders WHERE period = @period ORDER BY roundNumberId DESC LIMIT 1;";
                cmd.Parameters.AddWithValue("period", period);
                return id = (int)cmd.ExecuteScalar();
            }
        }
    }
    catch (NullReferenceException e)
    {
        Debug.Write(e.Message);
        Debug.WriteLine("Because of a new period, started with 1 again. Period: " + period + ".");
        return id = 1;
    }
}

Так это codepart мои вопросы:

  1. Это хорошо, чтобы попробовать/catch блок снаружи с помощью инструкция блок?
  2. Есть ли лучший способ для обработки исключений?
  3. Мне нужно попасть в блок catch?

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

Это правильный способ справиться с этим?



Комментарии
4 ответа

Некоторые замечания:


  • Не писать ADO.NET код по руке; вместо того, чтобы использовать ORM, как щеголь.

  • Почему бы не использовать MAX() -- что, я думаю, поддерживается в PostgreSQL -- вместо ORDER BY roundNumberId DESC LIMIT 1?


    SELECT MAX(column_name)  
    FROM table_name
    WHERE condition;


  • Не поставить бизнес-логики в исключения. Вместо того, чтобы сделать этот метод int?
    TryGetRoundNumberId()
    и пусть вызывающий код решить проблему, когда возвращается значение null.

    Или, возможно, предоставить по умолчанию, например int TryGetRoundNumberId(int defaultValue), так что вы получите что-то вдоль этих линий:

    using (var sqlConnection = new SqlConnection(_connectionString))
    {
    sqlConnection.Open();

    using (var sqlCommand = new SqlCommand())
    {
    // snip parameters etc.

    var result = (int?)sqlCommand.ExecuteScalar();
    if (result.HasValue)
    {
    return result.Value;
    }
    else
    {
    return defaultValue;
    }
    }
    }


4
ответ дан 6 марта 2018 в 01:03 Источник Поделиться

Только одно короткое замечание...


catch (NullReferenceException e)

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

4
ответ дан 6 марта 2018 в 03:03 Источник Поделиться


Это хорошо, чтобы попробовать/catch блок снаружи оператором?

Я не вижу видимых причин почему try/catch вне using блок может вызвать проблемы как одноразовые обернутый using блоки будут утилизированы, как только они выйдут из области видимости, независимо от исключений или нет.


Есть ли лучший способ для обработки исключений?
Мне нужно попасть в блок catch?

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

private int GetLastRoundNumber(int period) {        
using (var connection = new NpgsqlConnection(_entwConnection)) {
connection.Open();
using (var command = connection.CreateCommand()) {
command.CommandType = CommandType.Text;
command.CommandText = "SELECT roundNumberId FROM race.folders WHERE period = @period ORDER BY roundNumberId DESC LIMIT 1;";
command.Parameters.AddWithValue("period", period);
var result = command.ExecuteScalar();
if (result == null) {
Debug.WriteLine("Because of a new period, started with 1 again. Period: " + period + ".");
return 1;
}
return (int)result;
}
}
}

Каких-либо исключений в приведенном выше коде должна пузыриться обрабатываться абонента. Этот метод позволяет иметь единую ответственность, не смешивая сквозных проблем.

2
ответ дан 6 марта 2018 в 10:03 Источник Поделиться

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

Я бы вернулся к читателю

int id;
using (NpgsqlConnection con = new NpgsqlConnection(_entwConnection))
{
con.Open();
using (NpgsqlCommand cmd = con.CreateCommand())
{
cmd.CommandText = "SELECT roundNumberId FROM race.folders WHERE period = @period ORDER BY roundNumberId DESC LIMIT 1;";
cmd.Parameters.AddWithValue("period", period);
using(Reader rdr = cmd.ExectuteReader())
{
if(rdr.HasRows())
{
rdr.Read();
id = rdr.GetInt(0);
}
else
{
id = 1;
}
}
}
}
return id;

просто return id один раз в конце.

В try может быть внутри using. using (NpgsqlConnection con = new NpgsqlConnection(_entwConnection)) никогда не выдаст ошибку.

Но теперь вам не нужно, чтобы поймать любые ошибки, поэтому вам не нужно попробовать поймать.

0
ответ дан 6 марта 2018 в 12:03 Источник Поделиться