Как вы представляете нулевое значение на уровне доступа к данным (C #) - PullRequest
2 голосов
/ 22 декабря 2008

Просто интересно, есть ли лучший способ для DAL представлять нулевое значение (из обнуляемого столбца).

В настоящее время у нас есть собственный внутренний DAL, и мы представляем нулевое значение с помощью int.MinValue. Однако этот рост связан с тем, что разработчики думают, что при сравнении значений мы намеренно навязываем другое «добавленное» значение для int.MinValue, и тот факт, что int.MinValue используется для нулевого значения в слое DAL, сбивает с толку. Так что другие придумали NullValue из .net 2.0, но мы обнаружили, что есть проблемы с производительностью и синтаксисом, связанные с этим подходом:

Итак, что вы думаете об этом? Как другие известные ORM заботятся о нулевых значениях? Есть ли лучшая практика по этому вопросу?

Ответы [ 6 ]

10 голосов
/ 22 декабря 2008

Чтобы представить обнуляемое целое число, я бы использовал Nullable<int> (он же int?) каждый раз. Это именно то, для чего он предназначен. Вы предоставили несколько ссылок, но не могли бы вы указать точно , где ваша проблема с синтаксисом обнуляемых типов и где вы видели существенные проблемы с производительностью (учитывая, что вызов базы данных, вероятно, будет на намного дороже, чем любые преобразования, происходящие в процессе).

РЕДАКТИРОВАТЬ: Я заметил, что предпоследняя ссылка на разговор группы новостей с участием меня. Моя причина избавления от обнуляемых типов в этой ситуации заключается в том, что вопрос был связан с веб-сервисом, который может нуждаться в эффективной передаче нулевых значений платформе, которая не имеет обнуляемых типов значений. Я не думаю, что это относится к вашей ситуации, как вы ее описали.

1 голос
/ 22 декабря 2008

Добавлено как ответ, потому что это слишком долго, чтобы быть комментарием.

Если вам нужно засорять вашу кодовую базу Nullable.Compare, вы делаете это неправильно. Вам не следует сравнивать два Nullable<int> значения, если вы уже не знаете, что оба они не равны нулю.

Единственное исключение - в местах, где это совершенно неизбежно, например при агрегировании или сортировке. Если вы используете стандартные методы (например, Linq) для этого, вам не нужно реализовывать что-то особенное для этого, потому что Nullable<T> реализует IComparable<T>.

Существует причина, по которой в SQL Server любое выражение, содержащее термин NULL, оценивается как NULL. Если одним из терминов в выражении является NULL, результат выражения будет бессмысленным - если выражение явно не указывает (через ISNULL или COALESCE), что делать, если термин является NULL. Это решение должно приниматься в выражении или вокруг него, а не глобально.

Например, рассмотрим эту, казалось бы, простую логику:

if (qtyOrdered > qtyInStock)
{
   Reorder(qtyInStock - qtyOrdered);
}

Это вызовет исключение, если qtyInStock равно нулю. Что должен эта логика делать, если qtyInStock равен нулю? Мы не знаем: это вопрос, который необходимо учитывать при разработке бизнес-логики, и он еще не решен.

Но есть одна вещь, которую мы почти наверняка делаем знаем: если qtyInStock равно нулю, генерирование нового заказа для Int.MinValue - qtyOrdered предметов является неправильным ответом. И это то, что логика, как это будет делать, если вы используете магическое число для обозначения нулей. Логика нарушена, и она должна быть исправлена, а не скрыта.

1 голос
/ 22 декабря 2008

Спасибо за быстрый ответ.

Мы все еще решаем, какой из них использовать, разве я не знаю, как nullable будет работать с нашей стороны, но я согласился, что доступ к базе данных будет узким местом.

Проблема, с которой я сталкиваюсь при использовании nullable, на самом деле связана с другим поведением встроенного оператора .net, описанным в здесь .

Если я использую обнуляемый тип и если я хочу правильно сравнить два целых числа, мне придется засорять свою кодовую базу синтаксисом Nullable.Compare. Я не уверен, что это лучшее решение.

1 голос
/ 22 декабря 2008

Я использую такие типы, как int? и пр.

0 голосов
/ 22 декабря 2008

C.J. Date утверждает, что нули не должны существовать в контексте RDBMS, отчасти из-за этих проблем. Как вы их избегаете? Изменяя их дизайн: разделите ваши данные различными способами так, чтобы столбцы, которые были бы нулевыми, просто стали неактуальными и исключались из логического плана в такой ситуации. Другими словами, измените дизайн таблиц и столбцов таким образом, чтобы каждый столбец ограничивался NOT NULL, но также имел значимое значение (не нужно заменять пользовательских часовых, например int.MinValue).

Это много работы, и люди с радостью спорят, стоит ли это того, но если вы так сильно заботитесь о производительности и чистоте своей реализации, то, возможно, это то, что вы хотите.

0 голосов
/ 22 декабря 2008

На моем уровне доступа к данным он преобразует ноль в значения, которые имеют смысл для контекста. Цель моего DAL состоит в том, чтобы связать данные с приложением, поэтому DAL должен знать, что представляют собой данные, и тогда разработчик может вывести хорошее новое значение. Возможно, нулевой является правильным ответом на поле с нулевым целочисленным значением, возможно, сообщение об ошибке может появиться в текстовом поле.

Таким образом, когда мое приложение считывает данные, оно получает данные, а когда оно отображается конечному пользователю, они видят, что что-то было ноль и где текст должен быть «нет доступного текста». *

Используя int? просто выдвигает нулевую проблему на один уровень выше, и теперь я использую свой DAL.

...