Почему преобразование пустого значения в datetime2 вызывает ошибку преобразования в SQL?

В С# я получаю это значение для типа datetime2:

{01/01/0001 00:00:00}

Это потому, что клиент отправляет пустое значение. В базе выдает ошибку:

Преобразование типа данных datetime2 в тип данных datetime привело к получению значения вне допустимого диапазона.

@DateGeneral datetime2 = null

в базе данных и процедуре.

Как мне его покрыть?


person scaryghost    schedule 29.02.2020    source источник
comment
Лучше всего было бы проверить наличие пустых (строковых) значений и передать их как NULL в базу данных, чтобы как можно раньше избавиться от недопустимых данных. Возможно, добавьте больше контекста для конкретного способа обработки вашего ввода.   -  person Filburt    schedule 29.02.2020
comment
проблема в том, что он не приходит как ноль, если он отправлен пустым, он приходит 01/01/0001 00:00:00   -  person scaryghost    schedule 29.02.2020
comment
Проверьте ввод и установите значение SqlParameter на DBNull.Value при обнаружении фиктивного значения.   -  person Serg    schedule 29.02.2020


Ответы (4)


Это происходит потому, что DateTime является типом значения, не допускающим значение NULL. 01/01/0001 00:00:00 — это значение по умолчанию.

DateGeneral, с другой стороны, допускает значение NULL, что делает значение null в базе данных несовместимым с тем, что у вас есть в C#.

Чтобы решить эту проблему, используйте в своей программе C# тип данных DateTime?, допускающий значение NULL.

person Sergey Kalinichenko    schedule 29.02.2020
comment
проблема в том, что я не могу сделать его обнуляемым. - person scaryghost; 29.02.2020
comment
в С# я не могу сделать его обнуляемым. - person scaryghost; 29.02.2020
comment
потому что мы следуем WSDL, предоставленному нам клиентом, и это не дата-время, допускающее значение NULL. - person scaryghost; 29.02.2020
comment
есть ли что-нибудь, что я могу сделать на уровне db? - person scaryghost; 29.02.2020
comment
@scaryghost Подождите, WSDL находится на стороне веб-сервиса, а не на стороне БД, верно? Вы можете читать из БД в тип, допускающий значение NULL, а затем выполнять преобразование при создании объекта WSDL, например wsdlObj.DateGeneral = dbObj.NullableDateGeneral ?? new DateTime() - person Sergey Kalinichenko; 29.02.2020

вы должны использовать это, чтобы получить дату даты и времени datetime.value.tosrting()

person Muzzamil Asad    schedule 29.02.2020

.Net datetime сопоставляется с DateTime2 тип данных SQL-сервера

**Вот диапазон этих типов данных. ссылка **

  • Диапазон даты и времени: с 1753-01-01 по 9999-12-31

  • Диапазон DateTime2: от 0001-01-01 до 9999-12-31

Чтобы ваше решение работало, вот возможные исправления:

  1. Сделайте тип данных .net обнуляемым, если вашему свойству не нужно какое-либо значение.
  2. Сделайте явное преобразование DataType в .Net (уровень DAL), сопоставьте его с DataTime2 с помощью EF set Column[TypeName = "datetime2"] или в свободном коде .HasColumnType("datetime2")

  3. Укажите значение по умолчанию (в случае нуля из .net) в допустимом диапазоне.

person Raushan Kuamr Jha    schedule 29.02.2020
comment
if (GeneralDateI == DateTime.MinValue) { cmd.Parameters.Add(GeneralDate, SqlDbType.DateTime2).Value = DBNull.Value; } - person scaryghost; 29.02.2020
comment
Что делать, если значение явно установлено в DateTime.MinValue в репозитории кода (где-то). Если вы следуете этому подходу, должно быть какое-то вспомогательное поле или флаг с информацией о том, является ли оно явно установленным значением из кода или значением по умолчанию. - person Raushan Kuamr Jha; 29.02.2020

Сервер Sql DateTime2s Диапазон дат шире, чем у DateTime. Если вы не можете изменить свой код С#, добавьте очищающий код в свой процесс, вроде

create procedure myproc (.. ,@DateGeneral datetime2 = null, ..)
as
..
-- DATETIME compatiblity check
if (@DateGeneral < DATEFROMPARTS(1753,1,1)) then
   @DateGeneral = null;
person Serg    schedule 29.02.2020
comment
Я сделал это: if (GeneralDate == DateTime.MinValue) { cmd.Parameters.Add(GeneralDate, SqlDbType.DateTime2).Value = DBNull.Value; } Это нормально? - person scaryghost; 29.02.2020
comment
Не могу сказать без контекста. Вы также можете просто пропустить добавление параметра, и сервер Sql будет использовать значение по умолчанию @DateGeneral datetime2 = null - person Serg; 29.02.2020