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

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

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

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

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

Столбец даты установлен в DateTime следующим образом:

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

Вопрос

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

Ответ 1

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

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


В стороне, правильный способ получить объект Type для конструктора DataColumn - это ключевое слово typeof, которое на несколько порядков быстрее.

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

new DataColumn("myDate", typeof(DateTime))

Ответ 2

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

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

Ответ 3

Обе карты 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 обрабатывал его.

Марк

Ответ 4

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

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

Ответ 5

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

01/01/0001 00:00:00

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

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

Ответ 6

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

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

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


Шаги по разрешению

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

  • Выберите объект и свойство времени даты
  • Выберите StoreGeneratedPattern
  • Установите Computed

Диалоговое окно типа модели модели модели EF


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

DEFAULT (GETDATE()) FOR [DateCreated].

Ответ 7

Этот меня сводил с ума. Я хотел бы избежать использования даты с датой сбрасывания (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;
                    }
                }
            }
        }
    }
}

Ответ 8

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

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

Ответ 9

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

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

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

movie.DateAdded = System.DateTime.Now

Ответ 10

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

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

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

Ответ 11

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

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

Использовать объект DateTime с нулевым значением.
  public DateTime? PurchaseDate {get; задавать; }

Если вы используете сущность framework Задайте свойство nullable в файле edmx True

Задайте свойство nullable в файле edmx равным ** True **

Ответ 12

Как уже отмечалось andyuk, это может произойти, когда значение NULL присваивается неопределяемому DateTime. Рассмотрите возможность изменения DateTime на DateTime? или Nullable < DateTime. Имейте в виду, что если вы используете Dependency Property, также убедитесь, что ваш тип свойства зависимостей также является типом DateTime с нулевым значением.

Ниже приведен пример реальной неполной настройки DateTime в DateTime?, которая вызывает нечетное поведение

введите описание изображения здесь

Ответ 13

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

Достичь решения можно двумя способами.

  • Чтобы использовать тип данных datetime в Entity Framwork 4, вам необходимо переключить ProviderManifestToken в edmx файл на "2005".
  • Если вы установите соответствующее поле как "Разрешить Null" (оно преобразует его в NULLABLE), значит, EF автоматически использует даты в качестве даты и времени.

Ответ 14

Создан базовый класс, основанный на реализации @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.)
 }

Ответ 16

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

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

В файле web.config.

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

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

: D

Ответ 17

Добавление этого кода в класс в ASP.NET сработало для меня:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Properties<DateTime>().Configure(c => c.HasColumnType("datetime2"));
}

Ответ 18

Я знаю об этой проблеме, и вы все должны быть тоже

https://en.wikipedia.org/wiki/Year_2038_problem

В SQL был создан новый тип поля, чтобы избежать этой проблемы (datetime2).

Этот тип поля "Дата" имеет те же значения диапазона, что и класс DateTime.Net. Это решит все ваши проблемы, поэтому я думаю, что лучший способ решить это - изменить тип столбца вашей базы данных (это не повлияет на данные вашей таблицы).

Ответ 19

Проверьте следующие два: 1) Это поле не имеет значения NULL. Например:

 public DateTime MyDate { get; set; }

Заменить на:

public DateTime MyDate { get; set; }=DateTime.Now;

2) Снова обновите базу данных. Например:

db=new MyDb();

Ответ 20

Проблема с унаследованным атрибутом datetime

Это сообщение об ошибке часто отображается, когда поле даты без ненулевого значения имеет значение null во время вставки/обновления. Одной из причин может быть наследство.

Если ваша дата унаследована от базового класса, и вы не делаете отображение, EF не будет читать ее значение.

для дополнительной информации:https://weblogs.asp.net/manavi/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-3-table-per-concrete-type-tpc-and-choosing-strategy-guidelines

Ответ 21

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

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