将datetime2数据类型转换为日期时间数据类型会导致超出范围的值

时间:2011-01-05 20:14:02

标签: asp.net-mvc

我的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."}任何想法是什么问题?我假设编辑方法正在尝试将数据库中的发布值更新为已编辑的但由于某种原因它不喜欢它...虽然我不明白为什么涉及日期,因为它没有在控制器编辑方法?

24 个答案:

答案 0 :(得分:158)

问题在于,您正在使用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();

答案 1 :(得分:109)

这是人们在使用Entity Framework时遇到的常见错误。当与要保存的表关联的实体具有强制日期时间字段并且您没有使用某个值设置它时,会发生这种情况。

使用值01/01/1000创建默认日期时间对象,并将其用于代替null。这将发送到datetime列,该列可以保存1753-01-01 00:00:00之前的日期值,但不会之前,导致超出范围的异常。

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

答案 2 :(得分:36)

  

DATETIME支持1753/1/1   “永恒”(9999/12/31),而   DATETIME2支持0001/1/1至   永恒。

Msdn

<强>答案: 我想您尝试使用'0001/1/1'值保存DateTime。只需设置断点并调试它,如果是,则将DateTime替换为null或设置正常日期。

答案 3 :(得分: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;
                    }
                }
            }
        }
    }
}

答案 4 :(得分:9)

您还可以通过添加到模型(实体框架版本&gt; = 5)

来解决此问题
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime CreationDate { get; set; }

答案 5 :(得分:7)

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

答案 6 :(得分:4)

我在更改模型(代码优先)后出现此错误,如下所示:

public DateTime? DateCreated

public DateTime DateCreated

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

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

答案 7 :(得分:3)

就我而言,在我在数据库表中使用的类的初始化程序中,我没有将任何默认值设置为我的DateTime属性,因此导致@Andrew Orsich&中解释的问题#39;回答。所以我只是让属性可以为空。或者我也可以在构造函数中给它DateTime.Now。希望它可以帮到某人。

答案 8 :(得分:3)

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

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

那将获得所有DateTime和DateTime?模型中所有实体的属性。

答案 9 :(得分:2)

如果您使用的是Entity Framework版本&gt; = 5,那么将[DatabaseGenerated(DatabaseGeneratedOption.Computed)]注释应用于您的类的DateTime属性将允许数据库表的触发器完成输入日期以创建记录的工作。记录更新,而不会导致您的实体框架代码堵塞。

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

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

这类似于第6个答案,由Dongolo Jeno编写并由Gille Q编辑。

答案 10 :(得分:1)

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

因此,在保存更改之前,请确保您的模型具有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; }

答案 11 :(得分:1)

当您尝试更新实体时,通常会出现此问题。例如,您有一个实体,其中包含名为DateCreated的字段,该字段为 [必填] ,并且在插入记录时不会返回错误,但是当您要更新该特定实体时,

  

datetime2转换超出范围错误。

现在是解决方法:

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

示例:

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

将此内容添加到您的修改视图中,我向您保证不会出现该错误。

答案 12 :(得分:1)

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

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

bad param

答案 13 :(得分:0)

如果您访问数据库,可以将数据库列类型从datetime更改为datetime2(7) 它仍然会发送一个日期时间对象,它将被保存

答案 14 :(得分:0)

模型应具有可为空的日期时间。应该使用先前建议的检索必须修改的对象的方法来代替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();

答案 15 :(得分:0)

[解决]在实体框架代码中(我的情况)只需将DateTime更改为DateTime?即可解决我的问题。

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

答案 16 :(得分:0)

尝试让您的财产可以为空。

    public DateTime? Time{ get; set; }

为我工作。

答案 17 :(得分:0)

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

由于 NOT 使用EF针对SQL DB中的NOT NULL日期列分配了任何值,因此发生了此错误,并且通过分配相同的错误得到解决。

希望这会有所帮助!

答案 18 :(得分:0)

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

答案 19 :(得分:0)

您必须为日期变量启用null值:

 public Nullable<DateTime> MyDate{ get; set; }

答案 20 :(得分:0)

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

答案 21 :(得分: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.
        }

答案 22 :(得分:0)

可能还有别的东西,但是对于将来的读者,请检查您的日期时间格式。我有14个月了

答案 23 :(得分:0)

将“ CreateDate”:“ 0001-01-01 00:00:00”更改为“ CreateDate”:“ 2020-12-19 00:00:00”,

CreateDate类型为公共DateTime CreateDate

错误json:

{ “ keyValue”:1 “实体”: { “ TodoId”:1 “ SysId”:“ 3730e2b8-8d65-457a-bd50-041ce9705dc6”, “ AllowApproval”:否, “ ApprovalUrl”:null, “ ApprovalContent”:null, “ IsRead”:是的, “ ExpireTime”:“ 2020-12-19 00:00:00”, “创建日期”:“ 0001-01-01 00:00:00”, “ CreateBy”:null, “ ModifyDate”:“ 2020-12-18 9:42:10”, “ ModifyBy”:null, “ UserId”:“ f5250229-c6d1-4210-aed9-1c0287ab1ce3”, “ MessageUrl”:“ https://bing.com” } }

正确的json:

{ “ keyValue”:1 “实体”: { “ TodoId”:1 “ SysId”:“ 3730e2b8-8d65-457a-bd50-041ce9705dc6”, “ AllowApproval”:否, “ ApprovalUrl”:null, “ ApprovalContent”:null, “ IsRead”:是的, “ ExpireTime”:“ 2020-12-19 00:00:00”, “ CreateDate”:“ 2020-12-19 00:00:00”, “ CreateBy”:null, “ ModifyDate”:“ 2020-12-18 9:42:10”, “ ModifyBy”:null, “ UserId”:“ f5250229-c6d1-4210-aed9-1c0287ab1ce3”, “ MessageUrl”:“ https://bing.com” } }