Как безопасно привести нулевой результат из sqlreader в int?


У меня есть таблица, которая содержит нулевые значения, и мне нужно получить данные из таблицы с помощью SqlDataReader. Я не могу понять, как я могу безопасно бросить DBNull в int.

В данный момент я делаю это следующим образом:

...
reader = command.ExecuteReader();
while (reader.Read()) {
     int y = (reader["PublicationYear"] != null) ? Convert.ToInt32(reader["PublicationYear"]) : 0;
     ...
}
...

Но получение Object cannot be cast from DBNull to other types., когда PublicationYear равен нулю.

Как я могу безопасно получить значение?

Спасибо.

9 6

9 ответов:

Вы должны сравнивать reader["PublicationYear"] с DBNull.Value, а не null.

DBNull это не то же самое, что null. Вместо этого вы должны попробовать что-то вроде этого:

int y = (reader["PublicationYear"] != DBNull.Value) ? ...

Необходимо явно проверить, имеет ли возвращаемое значение тип DBNull

while (reader.Read()) {
     int y = (!reader["PublicationYear"] is DBNull) ? Convert.ToInt32(reader["PublicationYear"]) : 0;
     ...
}

На самом деле, вы можете сделать это сравнение по значению, а также по типу:

reader["PublicationYear"] != DBNull.Value
Короче говоря, вы можете ожидать, что DBNull будет возвращен для нулей из базы данных, а не сам null.

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

Фрагмент для демонстрации идеи

    SELECT ...
           ,ISNULL (PublicationYear, 0) as PublicationYear
           ...
    FROM sometable

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

Изменение

reader["PublicationYear"] != null

К

reader["PublicationYear"] != DBNull.Value

Это ошибка: (reader["PublicationYear"] != null) Вы должны проверить для DBNull.Значение....

int ord = reader.GetOrdinal("PublicationYear");
int y = reader.IsDBNull(ord) ? 0 : reader.GetInt32(ord);

Или, в качестве альтернативы:

object obj = reader["PublicationYear"];
int y = Convert.IsDBNull(obj) ? 0 : (int)obj;

Измените свой тест с (reader["PublicationYear"] != null) на (reader["PublicationYear"] != DBNull.Value).

Значения null базы данных следует сравнивать с DBNull.Значение

reader = command.ExecuteReader(); while (reader.Read()) { int y = (reader["PublicationYear"] != DBNull.Value) ? Convert.ToInt32(reader["PublicationYear"]) : 0; ... }