Учим DataContext правильно воспринимать Null и DBNull.Value в параметрах
- Категория: Код
- – Автор: Игорь (Администратор)
С каждым витком развития технологий взаимодействия с базой данных, изменялись представление об использовании параметров. Если вы использовали RerordSet в скриптовом ASP, то, наверное, ни один раз составляли запрос ручной вставкой в текст. Согласитесь, что намного проще добавить единственный параметр оператором "&", нежели каждый раз составлять корректный запрос и определять отдельный параметр. Ведь, последнее не только захламляло код, но и несколько удивляло. Зачем громоздить конструкции для простых и давно известных задач. Понятно, идеология, валидность и прочее. Но вопрос "зачем?" все равно оставался.
Приход DataSet-ов в Asp.Net несколько упростил задачу. Удобство обработки больших массивов данных. Никакой лишней возни с каждой строкой. Вам достаточно было один раз составить шаблон запроса сохранения. Если же вы использовали инструменты Visual Studio, то вам вообще ничего не приходилось делать. Просто загрузите схему БД и радуйтесь. Однако, желание составить запрос вручную все равно оставалось. Ну, никак не хочется ради одного двух параметров вызывать специальные функции для создания оных. Понятно, концептуальность и все дела. Тем не менее, вопрос "зачем?" все равно оставался.
Примечание: Конечно, у DataSet-ов были свои проблемы. Тем не мене, в данном случае это не важно, так как речь идет об использовании параметров и не более.
И вот, казалось бы, появился удобный инструмент для составления запросов, позволяющий решать давно известную задачу преобразования стандартных типов данных в типы базы данных. Linq2Sql. Вызовите ExecuteQuery. Укажите в теле запроса параметры в виде '{номер}' и передайте параметры в нужном порядке. Никаких лишних телодвижений. Нет эти страшных "концепций". Достаточно написать что-то вроде:
Но, на практике оказалось не все так замечательно. Дело в том, что функции Microsoft не умеют корректно обрабатывать Null / DBNull.Value. Несмотря на все заявления в MSDN. Т.е. если вы передадите null или DBNull.Value в качестве параметра, то вы увидите красивое сообщение с ошибкой:
- В случае Null - A query parameter cannot be of type 'System.Object'
- В случае DBNull.Value - Unexpected type code: DBNull (which give this as a stack trace)
Обычно, после такого рода ошибок в голове проносится что-то вроде "эх, опять все ручками составлять". Ведь, какое бы решение не было концептуальное и удобное, если оно не позволяет получать корректные результаты, то такое решение бессмысленно. Конечно, можно использовать пограничные значения и другие изощренные способы. Но, это все превратит ваш код в "нечто", если не сказать больше.
Тем не менее, есть способ намного проще. Дело в том, что если один из параметров оказался Null или DBNull.Value, то нужно просто это указать в теле запроса. Т.е. если бы stringParam из первого примера был бы null, то запрос должен выглядеть следующим образом:
При таком вызове, код выполнится без каких-либо проблем. Однако, от таких вызовов веет чем-то вроде "switch" и "if-else if-else". Так что если вы не любитель составлять большие и громоздкие конструкции вызовов, то стоит использовать небольшую обертку. Например, можно расширить стандартный набор функций DataContext. Получится примерно следующий код.
Теперь, единственное, что вам останется, это подключать расширение класса и вызывать вместо привычного ExecuteQuery функцию ExecuteQueryNull, которая будет преобразовывать запрос и формировать нужные параметры для исполнения запроса. При этом сам запрос и его параметры будут оставаться без изменения. Например, для первого запроса не будет уже важно нулевые ли значения у типов:
☕ Понравился обзор? Поделитесь с друзьями!
-
✎Простые решения JavaScript - дата и время (русский и iso формат) Код
-
✎Простые решения JavaScript - ссылки Код
-
-
-
-
-
✎Группировка данных по элементам диапазона в MSSQL Код
-
-
-