Доступ к базе данных С#: DBNull против null

У нас есть собственная ORM, которую мы здесь используем, и мы предоставляем строго типизированные оболочки для всех наших таблиц БД. Мы также позволяем выполнять слабо типизированный специальный SQL, но эти запросы по-прежнему проходят через один и тот же класс для получения значений из устройства чтения данных.

При настройке этого класса для работы с Oracle мы столкнулись с интересным вопросом. Лучше использовать DBNull.Value или null? Есть ли преимущества в использовании DBNull.Value? Кажется более «правильным» использовать null, так как мы отделились от мира БД, но есть последствия (вы не можете просто слепо ToString() когда значение равно null, например), так что это определенно то, что нам нужно сделать осознанное решение о.


person David Wengier    schedule 15.08.2008    source источник


Ответы (4)


Я считаю, что лучше использовать null вместо DB null.

Причина в том, что, как вы сказали, вы отделяете себя от мира БД.

Как правило, рекомендуется проверять ссылочные типы, чтобы убедиться, что они в любом случае не равны нулю. Вы собираетесь проверять значение null для вещей, отличных от данных БД, и я считаю, что лучше всего поддерживать согласованность во всей системе и использовать значение null, а не DBNull.

В конечном счете, архитектурно я считаю, что это лучшее решение.

person Dan Herbert    schedule 16.08.2008

Если вы написали свой собственный ORM, я бы сказал, просто используйте null, так как вы можете использовать его по своему усмотрению. Я считаю, что DBNull изначально использовался только для того, чтобы обойти тот факт, что типы значений (int, DateTime и т. д.) не могли быть нулевыми, поэтому вместо того, чтобы возвращать какое-то значение, например ноль или DateTime.Min, которое подразумевает null (плохой, плохой), они создали DBNull, чтобы указать на это. Возможно, в этом было что-то большее, но я всегда предполагал, что причина в этом. Однако теперь, когда в C# 3.0 появились типы, допускающие значение NULL, DBNull больше не нужен. На самом деле, LINQ to SQL просто везде использует null. Совершенно никаких проблем. Примите будущее... используйте null. ;-)

person jeremcc    schedule 16.08.2008
comment
Я думаю, что у DBNull все еще есть применение. По крайней мере, с помощью sqlite я могу проверить, хранится ли значение, возвращаемое ExecuteScalar(), в базе данных явно или нет. Рассмотрим таблицу foo(a int, b int); с одной строкой (1, ноль). Если бы мы выполнили ExecuteScalar по команде SELECT b FROM foo WHERE A = 1, она вернула бы DBNull.Value (строка существует, но хранится нуль). Если бы я вызвал ExecuteScalar для SELECT b FROM foo WHERE A = 2, он вернул бы null (такой строки не существует). Предположительно, вы могли бы добиться того же результата с DataReader, но я ценю удобство. - person fostandy; 29.11.2009
comment
Интересно. При использовании ORM для доступа к БД я не часто явно использую ExecuteScalar в своем коде. Обычно я получаю полные объекты сущностей и таким образом смотрю на их значения. Итак, если сам объект равен нулю, это одно, а если значение равно нулю, это что-то другое. Просто разные способы сделать это. Я признаю, что ExecuteScalar более эффективен, если вам нужно только одно значение. - person jeremcc; 04.12.2009

Судя по имеющемуся у меня опыту, .NET DataTables и TableAdapters лучше работают с DBNull. Он также открывает несколько специальных методов, если они строго типизированы, например, DataRow.IsFirstNameNull, когда он используется.

Я хотел бы дать вам лучший технический ответ, чем этот, но для меня суть в том, чтобы использовать DBNull при работе с объектами, связанными с базой данных, а затем использовать «стандартный» нуль, когда я имею дело с объектами и кодом, связанным с .NET.

person Dillie-O    schedule 15.08.2008

Используйте DBNull.
Мы столкнулись с некоторыми проблемами при использовании null.
Если я правильно помню, вы не можете ВСТАВИТЬ нулевое значение в поле, только DBNull.
Может быть связано только с Oracle, извините, я не знаю узнать подробности больше.

person John Smithers    schedule 15.08.2008