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

В моем HomeController есть следующий код:

    public ActionResult Edit(int id)
    {
        var ArticleToEdit = (from m in _db.ArticleSet where m.storyId == id select m).First();
        return View(ArticleToEdit);
    }

    [ValidateInput(false)]
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Edit(Article ArticleToEdit)
    {

        var originalArticle = (from m in _db.ArticleSet where m.storyId == ArticleToEdit.storyId select m).First();
        if (!ModelState.IsValid)
            return View(originalArticle);

        _db.ApplyPropertyChanges(originalArticle.EntityKey.EntitySetName, ArticleToEdit);
        _db.SaveChanges();
        return RedirectToAction("Index");

    }

И это вид метода Edit:

<% using (Html.BeginForm()) {%>

    <fieldset>
        <legend>Fields</legend>
        <p>
            <label for="headline">Headline</label>
            <%= Html.TextBox("headline") %>
        </p>
        <p>
            <label for="story">Story <span>( HTML Allowed )</span></label>
            <%= Html.TextArea("story") %>
        </p>
        <p>
            <label for="image">Image URL</label>
            <%= Html.TextBox("image") %>
        </p>
        <p>
            <input type="submit" value="Post" />
        </p>
    </fieldset>

<% } %>

Когда я нажимаю кнопку отправки, я получаю сообщение об ошибке: {"The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value.\r\nThe statement has been terminated."} Любые идеи, в чем проблема? Я предполагаю, что метод редактирования пытается обновить опубликованное значение в БД до отредактированного, но по какой-то причине ему это не нравится... Хотя я не понимаю, почему используется дата, поскольку она не упоминается в метод контроллера для редактирования?

Ответ 1

Проблема заключается в том, что вы используете ApplyPropertyChanges с объектом модели, который был заполнен только данными в форме (заголовок, история и изображение). ApplyPropertyChanges применяет изменения ко всем свойствам объекта, включая ваш неинициализированный DateTime, который установлен в 0001-01-01, который находится за пределами диапазона SQL Server DateTime.

Вместо того, чтобы использовать ApplyPropertyChanges, я бы предложил получить измененный объект, изменить конкретные поля, которые редактирует ваша форма, а затем сохранить объект с этими изменениями; Таким образом, изменяются только измененные поля. В качестве альтернативы вы можете поместить скрытые входы на свою страницу с другими заполненными полями, но это не будет очень дружественным с одновременными изменениями.

Update:

Здесь показан непроверенный образец простого обновления некоторых полей вашего объекта (предполагается, что вы используете LINQ to SQL):

var story = _db.ArticleSet.First(a => a.storyId == ArticleToEdit.storyId);
story.headline = ArticleToEdit.headline;
story.story = ArticleToEdit.story;
story.image = ArticleToEdit.image;
story.modifiedDate = DateTime.Now;
_db.SubmitChanges();

Ответ 2

Это обычная ошибка, с которой сталкиваются люди при использовании Entity Framework. Это происходит, когда объект, связанный с сохраненной таблицей, имеет обязательное поле datetime, и вы не устанавливаете его с некоторым значением.

Объект datetime по умолчанию создается со значением 01/01/1000 и будет использоваться вместо null. Это будет отправлено в столбец datetime, который может содержать значения даты от 1753-01-01 00:00:00, но не раньше, что приведет к исключению вне диапазона.

Эта ошибка может быть решена путем изменения поля базы данных для принятия значения null или инициализации поля со значением.

Ответ 3

DATETIME поддерживает 1753/1/1 до "вечности" (9999/12/31), а DATETIME2 поддерживает 0001/1/1 до вечности.

MSDN

Ответ: Я полагаю, вы пытаетесь сохранить DateTime со значением "0001/1/1". Просто установите точку останова и отладьте ее, если так, то замените DateTime на null или установите обычную дату.

Ответ 4

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

Ответ 5

Вы также можете устранить эту проблему, добавив в модель (версия Entity Framework >= 5)

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime CreationDate { get; set; }

Ответ 6

Если у вас есть столбец, который является datetime и имеет значение null, вы получите эту ошибку. Я рекомендую установить значение для передачи объекта перед .SaveChanges();

Ответ 7

Я получил эту ошибку после того, как я изменил свою модель (сначала код) следующим образом:

public DateTime? DateCreated

к

public DateTime DateCreated

Существующие строки с нулевым значением в DateCreated вызвали эту ошибку. Поэтому я должен был использовать SQL UPDATE Statement вручную для инициализации поля со стандартным значением.

Другим решением может быть указание значения по умолчанию для файла.

Ответ 8

В моем случае, в инициализаторе из класса, который я использовал в таблице базы данных, я не устанавливал значение по умолчанию для своего свойства DateTime, поэтому в результате возникла проблема, объясняемая в ответе @Andrew Orsich. Поэтому я просто сделал свойство nullable. Или я мог бы также дать ему DateTime.Now в конструкторе. Надеюсь, это поможет кому-то.

Ответ 9

Похоже, вы используете сущность framework. Мое решение состояло в том, чтобы переключить все столбцы datetime на datetime2 и использовать datetime2 для любых новых столбцов, другими словами, чтобы EF использовал datetime2 по умолчанию. Добавьте это в метод OnModelCreating в вашем контексте:

modelBuilder.Properties<DateTime>().Configure(c => c.HasColumnType("datetime2"));

Что получит все DateTime и DateTime? свойства для всех объектов вашей модели.

Ответ 10

Если вы используете версию Entity Framework> = 5, то применение аннотации [DatabaseGenerated (DatabaseGeneratedOption.Computed)] к вашим свойствам DateTime вашего класса позволит триггеру таблицы базы данных выполнять свою работу по вводу дат для создания записей и обновления записей, не вызывая ваш код Entity Framework для gag.

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime DateCreated { get; set; }

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime DateUpdated { get; set; }

Это похоже на 6-й ответ, написанный Dongolo Jeno и отредактированный Gille Q.

Ответ 11

Кроме того, если вы не знаете часть кода, где произошла ошибка, вы можете выполнить "плохое" выполнение sql, используя sql-профайлер, интегрированный в mssql.

Параметр bad datetime будет отображаться примерно так:

bad param

Ответ 12

У меня была та же проблема, к сожалению, у меня есть два свойства DateTime для моей модели, а одно свойство DateTime имеет значение null до того, как я сделаю SaveChanges.

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

public DateTime DateAdded { get; set; }   //This DateTime always has a value before persisting to the database.
public DateTime ReleaseDate { get; set; }  //I forgot that this property doesn't have to have DateTime, so it will trigger an error

Таким образом, это решает мою проблему, поэтому необходимо убедиться, что ваша модельная дата верна, прежде чем перейти к базе данных:

public DateTime DateAdded { get; set; }
public DateTime? ReleaseDate { get; set; }

Ответ 13

Эта проблема обычно возникает, когда вы пытаетесь обновить сущность. Например, у вас есть объект, который содержит поле с именем DateCreated которое является [Обязательным], и когда вы вставляете запись, ошибка не возвращается, но когда вы хотите обновить этот конкретный объект, вы получаете

преобразование datetime2 вне диапазона.

Теперь вот решение:

В вашем представлении редактирования, т.е. edit.cshtml для пользователей MVC, все, что вам нужно сделать, это добавить скрытое поле формы для вашего DateCreated чуть ниже скрытого поля для первичного ключа данных редактирования.

Пример:

@Html.HiddenFor(model => model.DateCreated)

Добавив это к вашему редактируемому виду, у вас никогда не будет этой ошибки, я вас уверяю.

Ответ 14

Попробуйте сделать ваше свойство нулевым.

    public DateTime? Time{ get; set; }

Работал для меня.

Ответ 15

Если у вас есть доступ к БД, вы можете изменить тип столбца БД с даты и времени на datetime2 (7) он все равно отправит объект datetime, и он будет сохранен

Ответ 16

Модель должна иметь значение NULL для NULL. Ранее предложенный метод извлечения объекта, который должен быть изменен, должен использоваться вместо ApplyPropertyChanges. В моем случае у меня был этот метод для сохранения моего объекта:

public ActionResult Save(QCFeedbackViewModel item)

И затем в службе, я получаю, используя:

RETURNED = item.RETURNED.HasValue ? Convert.ToDateTime(item.RETURNED) : (DateTime?)null 

Полный код обслуживания приведен ниже:

 var add = new QC_LOG_FEEDBACK()
            {

                QCLOG_ID = item.QCLOG_ID,
                PRE_QC_FEEDBACK = item.PRE_QC_FEEDBACK,
                RETURNED = item.RETURNED.HasValue ? Convert.ToDateTime(item.RETURNED) : (DateTime?)null,
                PRE_QC_RETURN = item.PRE_QC_RETURN.HasValue ? Convert.ToDateTime(item.PRE_QC_RETURN) : (DateTime?)null,
                FEEDBACK_APPROVED = item.FEEDBACK_APPROVED,
                QC_COMMENTS = item.QC_COMMENTS,
                FEEDBACK = item.FEEDBACK
            };

            _context.QC_LOG_FEEDBACK.Add(add);
            _context.SaveChanges();

Ответ 17

[Исправлено] В Entity Framework Code Сначала (мой случай), просто изменяя DateTime на DateTime? решить мою проблему.

/*from*/ public DateTime SubmitDate { get; set; }
/*to  */ public DateTime? SubmitDate { get; set; }

Ответ 18

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

Эта ошибка произошла, когда из-за НЕ назначено какое-либо значение столбцу даты NOT NULL в БД SQL с помощью EF, и была устранена путем присвоения того же значения.

Надеюсь это поможет!

Ответ 19

Получил эту проблему, когда создал мои классы из подхода Database First. Решено с помощью простого Convert.DateTime(dateCausingProblem) На самом деле, всегда пытайтесь преобразовать значения перед передачей, это спасает вас от неожиданных значений.