В чем смысл DBNull?
в .NET есть null ссылка, которая используется везде, чтобы обозначить, что ссылка на объект пуста, а затем есть DBNull, который используется драйверами базы данных (и несколькими другими) для обозначения... почти то же самое. Естественно, это создает много путаницы, и процедуры преобразования должны быть выработаны и т. д.
так почему же оригинальные авторы .NET решили сделать это? Для меня это не имеет смысла. Их документация не имеет смысла либо:
класс DBNull представляет несуществующее значение. Например, в базе данных столбец в строке таблицы может вообще не содержать никаких данных. То есть столбец считается вообще не существующим, а просто не имеющим значения. Объект DBNull представляет несуществующий столбец. Кроме того, COM-взаимодействие использует класс DBNull для различения варианта VT_NULL, который указывает несуществующее значение, и варианта VT_EMPTY, который указывает неопределенное значение.
что это за чушь про "несуществующую колонку"? Столбец существует, он просто не имеет значения для конкретной строки. Если бы он не существовал, я бы получил исключение, пытаясь получить доступ к конкретной ячейке, а не DBNull! Я могу понять необходимость различать VT_NULL и VT_EMPTY, но тогда почему бы не сделать COMEmpty вместо класса? Это было бы гораздо аккуратнее вписывается во всю .NET framework.
Я что-то пропустила? Может ли кто-нибудь пролить какой-то свет почему DBNull был изобретен и какие проблемы он помогает решать?
5 ответов:
дело в том, что в некоторых ситуациях существует разница между значением базы данных null и .NET Null.
например. Если вы используете ExecuteScalar (который возвращает первый столбец первой строки в результирующем наборе), и вы получаете null назад, это означает, что выполненный SQL не вернул никаких значений. Если вы возвращаете DBNull, это означает, что значение было возвращено SQL, и оно было NULL. Вы должны быть в состоянии сказать, разницу.
я собираюсь не согласиться с тенденцией здесь. Я пойду на запись:
я с этим не согласен
DBNullслужит любой полезной цели; это добавляет ненужную путаницу, в то время как вклад практически не имеет значения.часто выдвигается аргумент, что
nullявляется недопустимой ссылкой, и этоDBNullявляется нулевым шаблоном объекта;ни то, ни другое не верно. Например:int? x = null;это не "недопустимая ссылка"; это
nullзначение. Действительноnullозначает все, что вы хотите, чтобы это означало, и, честно говоря, у меня нет абсолютно никаких проблем с работой со значениями, которые могут бытьnull(действительно, даже в SQL нам нужно правильно работать сnull- здесь ничего не меняется). Равным образом," шаблон нулевого объекта "имеет смысл только в том случае, если вы действительно рассматриваете его как объект в терминах ООП, но если у нас есть значение, которое может быть" наше значение или
вы используете DBNull для недостающих данных. Null в языке .NET означает, что нет указателя для объекта/переменной.
DBNull отсутствуют данные:http://msdn.microsoft.com/en-us/library/system.dbnull.value.aspx
влияние отсутствующих данных на статистику:
есть некоторые различия между CLR null и DBNull. Во-первых, null в реляционных базах данных имеет различную семантику "равно": null не равно null. Среда CLR нуль равен нулю.
но я подозреваю, что основная причина заключается в том, как значения параметров по умолчанию работают в SQL server и реализации поставщика.
чтобы увидеть разницу, нужно создать процедуру с параметром, который имеет значение по умолчанию:
CREATE PROC [Echo] @s varchar(MAX) = 'hello' AS SELECT @s [Echo]хорошо структурированный DAL код должен отделять создание команд от использования (чтобы можно было использовать одну и ту же команду много раз, например, чтобы эффективно вызывать хранимую процедуру много раз). Напишите метод, который возвращает команду SqlCommand, представляющую приведенную выше процедуру:
SqlCommand GetEchoProc() { var cmd = new SqlCommand("Echo"); cmd.Parameters.Add("@s", SqlDbType.VarChar); return cmd; }Если вы теперь вызываете команду без установки параметра @s или установите его значение (CLR) null, он будет использовать значение по умолчанию "hello". Если, с другой стороны, вы установили значение параметра в DBNull.Значение, он будет использовать это и Эхо Значение dbnull.Значение.
поскольку есть два разных результата с использованием CLR null или database null в качестве значения параметра, вы не можете представить оба случая только с одним из них. Если бы CLR null был единственным, он должен был бы работать так, как DBNull.Значение сегодня. Один из способов указать поставщику "я хочу использовать значение по умолчанию" может заключаться в том, чтобы не объявлять параметр вообще (параметр со значением по умолчанию, конечно, имеет смысл описывать как "необязательный параметр"), но в сценарии если объект команды кэшируется и используется повторно, это приводит к удалению и повторному добавлению параметра.
Я не уверен, что я думаю, что DBNull была хорошей идеей или нет, но многие люди не знают о том, что я упомянул здесь, поэтому я решил, что это стоит упомянуть.
Comments