"Объект нельзя отбрасывать из DBNull в другие типы"

Когда мой сайт получает следующий бит кода, он падает с исключением следующим образом:

System.InvalidCastException: объект не может быть перенесен из DBNull в другие типы.

В интересах краткости я показываю только соответствующий код (это 4000 + LOC файл, который мне дал).

if (dr["STAGE"] is DBNull)
{
    dto.Stage = 1; // This is the line throwing the exception, according to stack trace
}
else
{
    dto.Stage = Convert.ToInt32(dr["STAGE"]);
}

Здесь dr - это объект DataRow, являющийся результатом запроса к базе данных, dto - это базовый класс, который просто содержит некоторые свойства, из которых dto.Stage является членом int.

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

Так может кто-нибудь предложить решение?

Ответ 1

@MarcGravell имел право на это в своем комментарии:

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

Ответ на

@Sergey просто неверен.

Ответ 2

Используйте == вместо is

if (dr["STAGE"] == DBNull.Value)
{

}

Ответ 3

Используйте этот несколько более эффективный подход

int stageOrdinal = dr.GetOrdinal("STAGE");
while (dr.Read()) {
     dto = new DataTransferObject();
     if (dr.IsDBNull(stageOrdinal)) {
         dto.Stage = 1;
     } else {
         dto.Stage = dr.GetInt32(stageOrdinal);
     }
     //TODO: retrieve other columns.
     dtoList.Add(dto);
}

Доступ к столбцам по их индексу происходит быстрее, чем доступ к ним по имени. Индекс столбца можно получить с помощью метода GetOrdinal DataReader. Это лучше всего сделать до цикла.

Ответ 5

Ниже приведен пример нулевого типа данных, который можно использовать для предотвращения ошибок DBNull. Нижеприведенный пример не является подлинным решением проблемы, но это пример того, как вы можете его решить. Подумайте об этом как о рыбалке, а не о рыбе.

Я вытащил это из http://msdn.microsoft.com/en-us/library/1t3y8s4s.aspx

class NullableExample
{
    static void Main()
    {
        int? num = null;
        if (num.HasValue == true)
        {
            System.Console.WriteLine("num = " + num.Value);
        }
        else
        {
            System.Console.WriteLine("num = Null");
        }

        // y is set to zero
        int y = num.GetValueOrDefault();

        // num.Value throws an InvalidOperationException if num.HasValue is false
        try
        {
            y = num.Value;
        }
        catch (System.InvalidOperationException e)
        {
            System.Console.WriteLine(e.Message);
        }
    }
}