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

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

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

преобразование типа данных datetime2 в тип данных datetime в результате вне диапазона значение

это означает, как читается, что мой datatable имеет тип DateTime2 и моя база данных a DateTime; что это неправильно.

столбец дата имеет значение DateTime вот так:

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

вопрос

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

17 ответов


какие даты у вас есть в колонке?

все ли они подходят в пределах диапазона типа?


в стороне, правильный способ получить


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

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


и 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 для его обработки.

Марк


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

obj.DateProperty = DateTime.now; // C#

для меня это было потому, что datetime был..

01/01/0001 00:00:00

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

DateTime FirstYearRegistered = Convert.ToDateTime(Collection["FirstYearRegistered"]);
if (FirstYearRegistered != DateTime.MinValue)
{
    vehicleData.DateFirstReg = FirstYearRegistered;
}  

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

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;
                    }
                }
            }
        }
    }
}

иногда 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].


Если мы не передадим поле Дата-время-дата, будет передана дата по умолчанию {1/1/0001 12:00:00 AM}.

но эта дата несовместима с работой фрейма сущности, поэтому она будет бросать преобразование типа данных datetime2 в тип данных datetime в результате вне диапазона значение

просто default DateTime.now в поле Дата, если дата не передается.

movie.DateAdded = System.DateTime.Now

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

 [Column(TypeName = "datetime2")]
 public DateTime? NullableDateTimePropUtc { get; set; }

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

вы все равно захотите сделать кучу тестов...

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


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

преобразование типа данных datetime2 в тип данных datetime в результате вне диапазона значение.

используйте объект DateTime с нулевым значением.
общественная datetime? PurchaseDate { get; set;}

Если вы используете entity framework Установить свойство nullable в файле edmx в правда

Set the nullable property in the edmx file to **True**


Entity Framework 4 работает с типом данных datetime2, поэтому в БД соответствующее поле должно быть datetime2 для SQL Server 2008.

для достижения решения есть два способа.

  1. чтобы использовать тип данных datetime в Entity Framwork 4, необходимо переключить ProviderManifestToken в edmx-файле на"2005".
  2. если вы установите соответствующее поле как Allow Null (оно преобразует его в NULLABLE) , то EF автоматически использует объекты date как значение datetime.

As andyuk уже указал, это может произойти, когда NULL значение присваивается не nullable DateTime


создал базовый класс на основе реализации @sky-dev. Таким образом, это можно легко применить к нескольким контекстам и сущностям.

public abstract class BaseDbContext<TEntity> : DbContext where TEntity : class
{
    public BaseDbContext(string connectionString)
        : base(connectionString)
    {
    }
    public override int SaveChanges()
    {

        UpdateDates();
        return base.SaveChanges();
    }

    private void UpdateDates()
    {
        foreach (var change in ChangeTracker.Entries<TEntity>())
        {
            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;
                    }
                }
            }
        }
    }
}

использование:

public class MyContext: BaseDbContext<MyEntities>
{

    /// <summary>
    /// Initializes a new instance of the <see cref="MyContext"/> class.
    /// </summary>
    public MyContext()
        : base("name=MyConnectionString")
    {
    }
    /// <summary>
    /// Initializes a new instance of the <see cref="MyContext"/> class.
    /// </summary>
    /// <param name="connectionString">The connection string.</param>
    public MyContext(string connectionString)
        : base(connectionString)
    {
    }

     //DBcontext class body here (methods, overrides, etc.)
 }

в моем случае мы отбрасывали дату в Datetime, и мы получили эту ошибку. что происходит, так это то, что дата имеет" более ориентированный на программиста " минимум 01/01/0001, в то время как Datetime застрял в 1753

объедините это с ошибкой сбора данных с нашей стороны, и вы получите свое исключение!


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

<globalization uiCulture="es" culture="es-CO" />

в интернете.конфигурационный файл.

часовой пояс на машине (сервере) был правильным (для локали CO), но веб-приложение этого не сделало. Эта настройка выполнена, и она снова работала нормально.

Off конечно, все даты имели значение.

: D


У вас будет столбец даты, который был установлен в lesathan минимальное значение разрешенного времени, например 1/1/1001.

чтобы преодолеть эту проблему, вы можете установить правильное значение datetime для свойства ur adn также установить другое магическое свойство, такое как IsSpecified=true.