datetime2数据类型到datetime数据类型的转换导致超出范围的值


176

我的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."}任何想法是什么问题?我假设edit方法正在尝试将数据库中的过帐值更新为已编辑的值,但由于某种原因,它并不喜欢它。尽管我不明白为什么要涉及日期,因为日期未提及控制器方法进行编辑?


1
modelBuilder.Entity<WorldInfo>().Property(d => d.CurrentTime).HasColumnType("datetime2");
安东尼·尼科尔斯

Answers:


168

问题是您使用ApplyPropertyChanges的模型对象仅填充了表单(标题,故事和图像)中的数据。 ApplyPropertyChanges将更改应用于对象的所有属性,包括未初始化的对象,将DateTime其设置为0001-01-01,这超出了SQL Server的范围DATETIME

建议您不要ApplyPropertyChanges检索,而是检索要修改的对象,更改表单编辑的特定字段,然后使用这些修改保存对象。这样,仅修改了字段。或者,您可以在页面中放置隐藏的输入,并填充其他字段,但这对并发编辑不是很友好。

更新:

这是一个未经测试的示例,仅更新了对象的某些字段(这是假设您正在使用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();

非常有帮助:)我想知道为什么未指定日期时更改了日期。您是否可以帮助更改Edit方法,使其不再使用ApplyPropertyChanges?由于我是ASP.NET的新手,因此目前还不完全了解它。谢谢朋友。
卡梅伦

如果我想将日期设置为当前日期该怎么办?文章已更新的日期时间?因为那可能是最好的选择,我想它可以与我正在使用的ApplyPropertyChanges一起使用。
卡梅伦

参见我的编辑(假定这modifiedDate是您的财产的名称)
Jacob

SubmitChanges在我的应用程序中不起作用:/是否可以将其添加story.modifiedDate = DateTime.Now;到当前代码中?谢谢
卡梅伦

1
当我们设置公共DateTime CreatedDate而不是公共DateTime时会发生此错误?CreatedDate,因为DateTime不能为null,所以为什么给出它超出范围的错误。这可能会有所帮助,但它解决了我的问题。
阿德南

116

这是人们在使用实体框架时遇到的常见错误。当与要保存的表关联的实体具有必填日期时间字段,而您未将其设置为某些值时,就会发生这种情况。

默认的datetime对象创建时的值为,01/01/1000并将代替null。这将被发送到datetime列,该列可以从1753-01-01 00:00:00开始(但不从此开始)保存日期值,导致超出范围的异常。

可以通过修改数据库字段以接受null或通过使用值初始化该字段来解决此错误。


3
当数据库中的datetime字段是可选的并且未设置值时,就会发生这种情况。因此,这不是普通人的错误,这是EF体系结构问题之一。
GSoft Consulting

1
我同意EF应该查看DB中的类型并相应地进行调整,或者抛出或至少抛出更精确的错误。从好的方面来看,我喜欢您的答案,因为您提供了2个选项,而不是通常的一个选项-用min值初始化文件。
DanteTheSmith

44

DATETIME支持1753/1/1到“永恒”(9999/12/31),同时 DATETIME2支持0001/1/1到永恒。

信息网

答: 我想您尝试DateTime使用“ 0001/1/1”值进行保存。只需设置断点并对其进行调试,如果可以,则将其替换DateTimenull或设置正常日期。


但是我应该在控制器中放入什么?调试只是提出了我上面发布的错误。谢谢。
卡梅伦

似乎错误-> _db.SaveChanges(); 您可以在此行之前设置断点...
Andrew Orsich 2011年

是的,确实做到了。然后,它说他们是SaveChanges上的一个错误,所以我看了InnerException,它说这是因为发布了错误,所以才是错误!
卡梅伦

您是否在_db.SaveChanges()之前检查了DateTime值?被称为?应该比“ 1753/1/1”好。
Andrew Orsich 2011年

originalArticle日期值为{18/10/2009 00:00:00},ArticleToEdit日期值为{01/01/0001 00:00:00},因此似乎正在尝试将日期更改为所有日期的1st不想,但由于格式相同,所以不解释为什么会引发错误吗?
卡梅伦

14

这个让我发疯。我想避免使用可为空的日期时间(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;
                    }
                }
            }
        }
    }
}

10

您还可以通过添加模型来解决此问题(Entity Framework版本> = 5)

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

8

如果您的列是datetime并且允许为null,则将出现此错误。我建议设置一个值以在.SaveChanges()之前传递给对象。


5

我按如下所示更改模型(首先输入代码)后收到此错误:

public DateTime? DateCreated

public DateTime DateCreated

当前在DateCreated中具有空值的行导致此错误。因此,我必须手动使用SQL UPDATE语句来使用标准值初始化字段。

另一种解决方案是指定字段的默认值。


3

就我而言,在数据库表中使用的类的初始值设定项中,我没有为DateTime属性设置任何默认值,因此导致了@Andrew Orsich的答案中所述的问题。所以我只是使该属性为可空。或者我也可以在构造函数中给它DateTime.Now。希望它能帮助某人。


3

看来您正在使用实体框架。我的解决方案是将所有datetime列切换为datetime2,并对任何新列使用datetime2,换句话说,默认情况下使EF使用datetime2。将此添加到上下文中的OnModelCreating方法中:

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

那会得到所有的DateTime和DateTime吗?模型中所有实体的属性。


2

我遇到了同样的问题,不幸的是,在执行SaveChanges之前,我的模型上有两个DateTime属性,而一个DateTime属性为null。

因此,在保存更改之前,请确保您的模型具有DateTime值,或者使其可以为null以防止错误:

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

2

如果使用的是Entity Framework版本> = 5,则将[DatabaseGenerated(DatabaseGeneratedOption.Computed)]注释应用于您的类的DateTime属性,将允许数据库表的触发器完成其输入记录创建和记录更新的日期的工作,而不会引起您要插入的实体框架代码。

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

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

这类似于Dongolo Jeno撰写并由Gille Q编辑的第六个答案。


1

另外,如果您不知道代码中发生错误的部分,则可以使用集成到mssql的sql profiler来分析“错误的” sql执行。

错误的日期时间参数将显示如下内容:

错误的参数


1

[已解决]在Entity Framework Code First(我的情况)中,只是DateTime为了DateTime?解决我的问题而进行了更改。

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

1

当您尝试更新实体时,通常会出现此问题。例如你有一个包含了一个名为领域的实体DateCreated[必需]当你插入记录,则返回没有错误,但是当你想更新特定的实体,您将得到

datetime2转换超出范围错误。

现在是解决方案:

在您的编辑视图上,即edit.cshtml对于MVC用户,您需要做的就是为您的广告添加一个隐藏的表单字段DateCreated的编辑数据主键的隐藏字段下面。

例:

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

将此添加到您的编辑视图中,我向您保证不会出现该错误。



0

尝试使您的媒体资源可为空。

    public DateTime? Time{ get; set; }

为我工作。



0

该模型应具有可为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();

0

错误: 将datetime2数据类型转换为datetime数据类型导致值超出范围。

由于“不”而发生此错误针对一个NOT NULL日期列在SQL数据库使用EF指定的任何值,被分配相同的解决。

希望这可以帮助!


0

从数据库优先方法创建我的类时遇到了这个问题。只需使用Convert.DateTime(dateCausingProblem)即可解决。事实上,始终尝试在传递之前转换值,这样可以避免意外的值。


0

您必须将日期字段的输入格式与所需的实体格式(yyyy / mm / dd)进行匹配


1
还提供了OP的问题的其他答案,这些答案已在一段时间前发布。发布答案时,请参阅:如何写一个好的答案?,请确保您添加新的解决方案或实质上更好的解释,尤其是在回答较旧的问题时。
help-info.de

0

我认为这方面最合乎逻辑的答案是将系统时钟设置为相关功能。

 [HttpPost]
        public ActionResult Yeni(tblKategori kategori)
        {
            kategori.CREATEDDATE = DateTime.Now;
            var ctx = new MvcDbStokEntities();
            ctx.tblKategori.Add(kategori);
            ctx.SaveChanges();
            return RedirectToAction("Index");//listele sayfasına yönlendir.
        }

0

可能还有其他事情,但是对于将来的读者,请检查您的日期时间格式。我有第十四个月

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.