Здесь есть много ответов с полезной информацией (и некоторой неправильной информацией), я хотел бы собрать все это вместе.
Короткий ответ на вопрос - проверить DBNull - с этим согласны почти все :)
Вместо использования вспомогательного метода для чтения значений NULL для каждого типа данных SQL универсальный метод позволяет нам решить эту проблему с помощью гораздо меньшего количества кода. Однако у вас не может быть единого универсального метода для типов значений Nullable и ссылочных типов, это подробно обсуждается в
типе Nullable как возможный универсальный параметр? и C # ограничение общего типа для всего обнуляемого .
Итак, исходя из ответов @ZXX и @getpsyched, мы в итоге получаем 2 метода для получения значений, допускающих значение NULL, и я добавил 3-й для ненулевых значений (он завершает набор на основе именования методов).
public static T? GetNullableValueType<T>(this SqlDataReader sqlDataReader, string columnName) where T : struct
{
int columnOrdinal = sqlDataReader.GetOrdinal(columnName);
return sqlDataReader.IsDBNull(columnOrdinal) ? (T?)null : sqlDataReader.GetFieldValue<T>(columnOrdinal);
}
public static T GetNullableReferenceType<T>(this SqlDataReader sqlDataReader, string columnName) where T : class
{
int columnOrdinal = sqlDataReader.GetOrdinal(columnName);
return sqlDataReader.IsDBNull(columnOrdinal) ? null : sqlDataReader.GetFieldValue<T>(columnOrdinal);
}
public static T GetNonNullValue<T>(this SqlDataReader sqlDataReader, string columnName)
{
int columnOrdinal = sqlDataReader.GetOrdinal(columnName);
return sqlDataReader.GetFieldValue<T>(columnOrdinal);
}
Я обычно использую имена столбцов, меняйте их, если вы используете индексы столбцов. Основываясь на названиях этих методов, я могу сказать, ожидаю ли я, что данные будут обнуляемыми или нет, что весьма полезно при просмотре кода, написанного давно.
Подсказки;
- Отсутствие обнуляемых столбцов в базе данных позволяет избежать этой проблемы. Если у вас есть контроль над базой данных, столбцы должны быть ненулевыми по умолчанию и обнуляться только при необходимости.
- Не приводите значения базы данных с помощью оператора C # «как», потому что, если приведение выполнено неправильно, оно молча вернет ноль.
- Использование выражения значения по умолчанию изменит нулевые значения базы данных на ненулевые значения для типов значений, таких как int, datetime, bit и т. Д.
Наконец, во время тестирования вышеуказанных методов для всех типов данных SQL Server, которые я обнаружил, вы не можете напрямую получить char [] из SqlDataReader, если вам нужен char [], вам нужно будет получить строку и использовать ToCharArray ().
int colIndex = reader.GetOrdinal(fieldname);
и легко перегрузитьSafeGetString
функцию @ marc_s .