Преобразование типа данных datetime2 в тип данных datetime приводит к выходу за пределы допустимого значения - PullRequest
336 голосов
/ 26 августа 2009

У меня есть таблица данных с 5 столбцами, где строка заполняется данными, а затем сохраняется в базе данных посредством транзакции.

При сохранении возвращается ошибка:

Преобразование типа данных datetime2 в тип данных datetime привело к значению вне диапазона

Из прочитанного следует, что моя таблица данных имеет тип DateTime2, а моя база данных - DateTime; это неправильно.

В столбце даты установлено значение DateTime, например:

new DataColumn("myDate", Type.GetType("System.DateTime"))

Вопрос

Может ли это быть решено в коде или что-то должно быть изменено на уровне базы данных?

Ответы [ 18 ]

685 голосов
/ 26 ноября 2010

Это может произойти, если вы не присвоите значение полю DateTime , когда поле не принимает значения NULL .

Это исправило это для меня!

148 голосов
/ 26 августа 2009

И DATETIME, и DATETIME2 отображаются на System.DateTime в .NET - вы действительно не можете выполнить "преобразование", поскольку это действительно тот же тип .NET.

См. Страницу документа MSDN: http://msdn.microsoft.com/en-us/library/bb675168.aspx

Есть два разных значения для "SqlDbType" для этих двух - вы можете указать их в своем определении DataColumn?

НО: на SQL Server поддерживаемый диапазон дат совсем другой.

DATETIME поддерживает 1753/1/1 в «вечность» (9999/12/31), в то время как DATETIME2 поддерживает 0001/1/1 в вечность.

Так что вам действительно нужно проверить год даты - если это до 1753 года, вам нужно изменить его на что-то ПОСЛЕ 1753 года, чтобы столбец DATETIME в SQL Server мог его обработать.

Марк

52 голосов
/ 26 августа 2009

Какие у вас даты в столбце?

Все ли они вписываются в диапазон типа?


Кроме того, правильным способом получения объекта Type для конструктора DataColumn является ключевое слово typeof, которое на несколько порядков быстрее.

Поэтому, чтобы создать столбец, вы должны написать

new DataColumn("myDate", typeof(DateTime))
40 голосов
/ 26 января 2011

В моей базе данных SQL Server 2008 у меня был столбец DateTime, помеченный как не обнуляемый, но с функцией GetDate() в качестве значения по умолчанию. При вставке нового объекта с использованием EF4 я получил эту ошибку, потому что я не передавал свойство DateTime в моем объекте явно. Я ожидал, что функция SQL будет обрабатывать дату для меня, но это не так. Моим решением было отправить значение даты из кода, а не полагаться на базу данных для ее генерации.

obj.DateProperty = DateTime.now; // C#
28 голосов
/ 04 июля 2013

для меня это было потому, что дата-время была ..

01/01/0001 00: 00: 00

в этом случае вы хотите присвоить нулевой объект EF DateTime ... используя мой FirstYearRegistered код в качестве примера

DateTime FirstYearRegistered = Convert.ToDateTime(Collection["FirstYearRegistered"]);
if (FirstYearRegistered != DateTime.MinValue)
{
    vehicleData.DateFirstReg = FirstYearRegistered;
}  
19 голосов
/ 05 марта 2015

Иногда EF не знает, что имеет дело с вычисляемым столбцом или триггером . По замыслу эти операции будут устанавливать значение вне EF после вставки.

Исправление заключается в том, чтобы указать Computed в EF edmx для этого столбца в свойстве StoreGeneratedPattern.

Для меня это было, когда в столбце был триггер, который вставил текущую дату и время, см. Ниже в третьем разделе. Порядок решения

В Visual Studio откройте страницу Model Browser, затем Model, затем Entity Types ->, затем

  1. Выберите объект и свойство даты и времени
  2. Выбрать StoreGeneratedPattern
  3. Установить на Computed

EF Model Browser Model Entity Type dialog


Для этой ситуации другие ответы - это обходные пути, для столбца нужно указать время / дату, когда была создана запись, и это задача SQL - выполнить триггер для добавления правильного времени. Например, этот триггер SQL:

DEFAULT (GETDATE()) FOR [DateCreated].

18 голосов
/ 02 июля 2012

Этот сводил меня с ума. Я хотел избежать использования обнуляемого времени даты (DateTime?). У меня не было возможности использовать datetime2 тип SQL Server 2008 либо

modelBuilder.Entity<MyEntity>().Property(e => e.MyDateColumn).HasColumnType("datetime2");

В итоге я выбрал следующее:

public class MyDb : DbContext
{
    public override int SaveChanges()
    {
        UpdateDates();
        return base.SaveChanges();
    }

    private void UpdateDates()
    {
        foreach (var change in ChangeTracker.Entries<MyEntityBaseClass>())
        {
            var values = change.CurrentValues;
            foreach (var name in values.PropertyNames)
            {
                var value = values[name];
                if (value is DateTime)
                {
                    var date = (DateTime)value;
                    if (date < SqlDateTime.MinValue.Value)
                    {
                        values[name] = SqlDateTime.MinValue.Value;
                    }
                    else if (date > SqlDateTime.MaxValue.Value)
                    {
                        values[name] = SqlDateTime.MaxValue.Value;
                    }
                }
            }
        }
    }
}
9 голосов
/ 17 февраля 2015

Я наткнулся на это и добавил следующее к своему свойству datetime:

 [Column(TypeName = "datetime2")]
 public DateTime? NullableDateTimePropUtc { get; set; }
9 голосов
/ 26 августа 2017

Если мы не передадим поле даты в дату, будет передана дата по умолчанию {01.01.10001 12:00:00 AM}.

Но эта дата не совместима с каркасом объекта, поэтому преобразование типа данных datetime2 в тип данных datetime привело к значению вне допустимого диапазона

Просто default DateTime.now в поле даты, если вы не передаете никакой даты.

movie.DateAdded = System.DateTime.Now
6 голосов
/ 26 августа 2009

Проще всего было бы изменить базу данных на использование datetime2 вместо datetime. Совместимость прекрасно работает, и вы не получите ошибок.

Вы все равно захотите провести кучу тестов ...

Ошибка, вероятно, связана с тем, что вы пытаетесь установить дату на год 0 или что-то в этом роде, но все зависит от того, где вы можете изменить что-либо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...