2014-10-28 3 views
1

Я использую Entity Framework в Visual Studio 2012, разрабатывая программу на C#. Я хочу добавить записи в таблицу базы данных. Запись (объект) включает в себя атрибут (TRANSACTION_DATE), который не допускает значения NULL, и это формат DateTime. В базе данных я стремлюсь к этому формату:Преобразование типа данных datetime2 в тип данных даты и времени приводило к значению вне диапазона

yyyy-MM-dd HH:mm:ss.fff

так я хочу передать текущую дату и время, мой код выглядит так:

newEntry.TRASACTION_DATE = DateTime.ParseExact(DateTime.Now.ToString(), 
          "yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture); 

, но это дает мне ошибку:

The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value.

Я хочу знать, почему он не преобразуется в формат, который я хочу?

ограничения: enter image description here

enter image description here

+2

Почему вы преобразовываете 'DateTime.Now' в строку и затем снова? Просто используйте 'DateTime.Now' ... и обратите внимание, что значение базы данных не будет * иметь * формат, по сути - формат, который он использует при преобразовании в строку, не имеет отношения к тому, что хранится. –

+0

, потому что это не в формате, который я хочу – lcc

+0

Я нахожу, что эти исключения «исключение вне времени» почти всегда относятся к попытке сохранить '01 -01-0001 00:00:00 'в базе данных, проверьте SQL отправляется в БД – paul

ответ

2

Вы не должны думать о базе данных как о хранении значений в определенном строчном формате вообще - не более, чем в нем хранятся числа как десятичные или шестнадцатеричные.

Вместо этого вы должны просто просмотреть его как дату/время, например.

// TODO: Do you really want the local time, rather than UtcNow? 
// TODO: Change TRANSACT_DATE to be TransactionDate ideally, to follow 
// .NET naming conventions 
newEntry.TRANSACT_DATE = DateTime.Now; 

При извлечении значения, вы должны получить DateTime в этой точке тоже. Затем, если вы хотите отобразить это значение для пользователя, вы можете применить определенный формат. Разным пользователям могут потребоваться разные форматы - и даже они могут отображать одну и ту же дату/время в разных часовых поясах.

Важно различать встроенные данные, которые вы храните (в данном случае дату/время), и текстовый формат, который используется для отображения любого конкретного контекста/приложения. Вам следует избегать конверсий в/из строк в любое время, когда вам это действительно не нужно. В идеале, это должно быть только на границе вашего приложения - например, при отображении текста пользователю или, возможно, сериализации в JSON или XML. Всякий раз, когда API позволяет вам не выполнить преобразование (например, с параметром базы данных), вы должны его избегать.

Что касается вашей текущей ошибки - возможно ли, что это другое поле, которое вы не заселяете, и поэтому использует default(DateTime), что было бы вне пределов досягаемости? Это будет иметь большой смысл - в то время как DateTime.Now действительно не должен быть вне пределов досягаемости, если только вы не применяли отдельное ограничение, или ваши системные часы - это мили.

+0

Я использовал этот путь в первую очередь, и это дало мне ту же ошибку. – lcc

+0

@ lcc: Это поможет, если вы расскажете нам больше о своей схеме и т. Д. Это должно быть абсолютно здорово. Есть ли у вас какие-либо другие ограничения в области базы данных? Возможно, оно заполняется автоматически базой данных? –

+0

@ lcc: см. Мой отредактированный ответ для другой возможности - интересно, полностью ли это поле. Не указано ли сообщение об ошибке *, значение которого находится за пределами допустимого диапазона? Сколько полей даты/времени имеет таблица базы данных? –

1

DateTime является независимо от формата. Формат презентации, такой как тот, который у вас есть, предназначен только для показа цели. Нет необходимости преобразовывать DateTime в строку и затем анализировать его с помощью специального формата. Просто назначить DateTime в своей области, как:

newEntry.TRASACTION_DATE = DateTime.Now; 

DateTime в SQL Server имеет ряд January 1, 1753, through December 31, 9999 Код синтаксического анализа в результате DateTime значение меньше 1753 года, и именно поэтому вы получаете исключение.

+0

Я использовал этот и дал мне ту же ошибку в начале, поэтому я хочу преобразовать ее в формат, который я хочу. – lcc

+0

@ lcc, какой тип данных «TRANSACTION_DATE» в БД? – Habib

+0

Формат DateTime @Habib – lcc

0

Можете ли вы переключить тип столбца в вашей базе данных на datetime2?Это Microsoft's recommendation. Некоторые .Net datetime значения не вписываются в datetime, тогда как тип datetime2 может содержать все .Net datetimes (и не будет вводить тонкие ошибки, например, округляя 2010-05-05 23:59:59.999 до 2010-05-06).

Обратите внимание, что в отличие от datetime, это не законно, чтобы рассматривать datetime2 как целое число (например, делая такие вещи, как mydate+1).

Если не указано значение datetime2, настройте код ORM, чтобы явно рассматривать эту дату как datetime, а не datetime2. Это не исправит вашу ошибку, но это приведет к сбою проверки, прежде чем отправлять запрос, а не потом, что упростит его исправление.

Независимо от вашего выбора, не используйте преобразование в/из строк для решения этой проблемы; это хак, который вызывает больше проблем, чем решает.

+0

В нем говорится, что мне пришлось бы отбросить таблицу или пересоздать таблицу, чтобы изменить тип столбца, который должен быть datetime2. И я не мог этого сделать. – lcc

+0

Как я могу настроить ORM-код, чтобы явно рассматривать эту дату как дату-время? – lcc

+0

@ lcc: Во время моего собственного тестирования удаление таблицы для изменения типа столбца не требуется при условии, что вы измените столбец через T-SQL, а не через интерфейс SMSS (конечно, связанный с схемой материал будет мешать), но, пожалуйста, проверьте это самостоятельно на тестовой БД. Что касается изменения ORM-кода, я не знаю, какой ORM вы используете. В случае 'SqlParameter' вы должны установить' DbType' 'System.Data.DbType.DateTime'. – Brian

Смежные вопросы

 Смежные вопросы