Сам стандарт HTML отвечает на Ваш вопрос:
Никакие два объекта не могут иметь тот же идентификатор, но произвольно, сумма объектов может иметь тот же класс.
Поэтому, если бы Вы хотите применить определенные атрибуты стиля CSS к единственному DIV только, который был бы идентификатором. Если Вы хотите, чтобы определенные атрибуты стиля относились к нескольким ОТДЕЛЕНИЯМ, которые должны быть классом.
Примечание, что можно смешать обоих. Можно заставить два ОТДЕЛЕНИЯ принадлежать тому же классу, но дать им различные идентификаторы. Можно тогда применить стиль, характерный и для к классу и для вещам, характерным для любой одной к их идентификатору. Браузер сначала применит стиль класса и затем идентификационный стиль, таким образом, идентификационные стили смогут перезаписать то, что класс установил прежде.
Вам нужно проверить IsDBNull
:
if(!SqlReader.IsDBNull(indexFirstName))
{
employee.FirstName = sqlreader.GetString(indexFirstName);
}
Это ваш единственный надежный способ обнаружить и справиться с этой ситуацией.
Я обернул эти вещи в методы расширения и стараюсь чтобы вернуть значение по умолчанию, если столбец действительно null
:
public static string SafeGetString(this SqlDataReader reader, int colIndex)
{
if(!reader.IsDBNull(colIndex))
return reader.GetString(colIndex);
return string.Empty;
}
Теперь вы можете назвать его так:
employee.FirstName = SqlReader.SafeGetString(indexFirstName);
, и вам никогда не придется беспокоиться об исключении или null
снова.
и / или использовать тернарный оператор с присваиванием:
employee.FirstName = rdr.IsDBNull(indexFirstName))?
String.Empty: rdr.GetString(indexFirstName);
заменить значение по умолчанию (при нулевом значении) соответствующим для каждого типа свойства ...
Мы используем серию статических методов для извлечения всех значений из наших считывателей данных. Итак, в этом случае мы будем вызывать DBUtils.GetString (sqlreader (indexFirstName))
Преимущество создания статических / общих методов состоит в том, что вам не нужно выполнять одни и те же проверки снова и снова. ..
Статические методы должны содержать код для проверки наличия нулей (см. Другие ответы на этой странице).
Я думаю, вам стоит использовать:
SqlReader.IsDBNull(indexFirstName)
Проверьте sqlreader.IsDBNull (indexFirstName)
, прежде чем пытаться его прочитать.
Я обычно заменяю нулевые значения в операторе SELECT чем-нибудь подходящим.
SELECT ISNULL(firstname, '') FROM people
Здесь я заменяю каждое значение null пустой строкой. В этом случае ваш код не приведет к ошибке.
Один из способов сделать это - проверить пустые значения db:
employee.FirstName = (sqlreader.IsDBNull(indexFirstName)
? ""
: sqlreader.GetString(indexFirstName));
IsDbNull (int)
обычно намного медленнее, чем использование таких методов, как GetSqlDateTime
, а затем сравнение с DBNull.Value
. Попробуйте эти методы расширения для SqlDataReader
.
public static T Def<T>(this SqlDataReader r, int ord)
{
var t = r.GetSqlValue(ord);
if (t == DBNull.Value) return default(T);
return ((INullable)t).IsNull ? default(T) : (T)t;
}
public static T? Val<T>(this SqlDataReader r, int ord) where T:struct
{
var t = r.GetSqlValue(ord);
if (t == DBNull.Value) return null;
return ((INullable)t).IsNull ? (T?)null : (T)t;
}
public static T Ref<T>(this SqlDataReader r, int ord) where T : class
{
var t = r.GetSqlValue(ord);
if (t == DBNull.Value) return null;
return ((INullable)t).IsNull ? null : (T)t;
}
Используйте их так:
var dd = r.Val<DateTime>(ords[4]);
var ii = r.Def<int>(ords[0]);
int nn = r.Def<int>(ords[0]);
Для значений по умолчанию следует использовать оператор as
в сочетании с оператором ??
. Типы значений должны быть считаны как nullable и заданы по умолчанию.
employee.FirstName = sqlreader[indexFirstName] as string;
employee.Age = sqlreader[indexAge] as int? ?? default(int);
Оператор as
обрабатывает приведение, включая проверку на DBNull.