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

278017 次浏览

DATETIME支持1753/1/1到 《永恒》(9999/12/31) DATETIME2支持0001/1/1到 永恒。

我不知道

回答: 我假设您尝试用“0001/1/1”值保存 DateTime。只需设置断点并调试它,如果是这样,然后用 null替换 DateTime或设置正常日期。

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

如果有一列是 datetime 并允许 null,则会得到这个错误。之前,我建议设置一个传递给对象的值。保存更改() ;

这个快把我逼疯了。我想避免使用可为空的日期时间(DateTime?)。我也没有选择使用 SQL2008的 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;
}
}
}
}
}
}

这是人们在使用实体框架时经常遇到的错误。当与要保存的表相关联的实体具有一个强制的 datetime 字段并且您没有为其设置某个值时,就会发生这种情况。

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

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

在我的例子中,在数据库表中使用的类的初始化器中,我没有为 DateTime 属性设置任何默认值,因此导致了@Andrew Orich 的回答中解释的问题。所以我让这个属性可以为零。或者我也可以给它日期时间。现在在构造函数中。希望能帮到别人。

此外,如果您不知道在哪些代码中发生了错误,您可以使用集成到 mssql 的 sql 探查器来分析“坏的”sql 执行。

糟糕的 datetime 参数将显示如下内容:

bad param

在我修改了我的模型(代码优先)之后,我得到了这个错误,如下所示:

public DateTime? DateCreated

public DateTime DateCreated

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

另一种解决方案是指定文件的默认值。

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

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

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

您还可以通过添加模型(实体框架版本 > = 5)来修复此问题

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

尝试使您的属性为空。

    public DateTime? Time{ get; set; }

对我有用。

如果可以访问 DB,则可以将 DB 列类型从 datetime 更改为 datetime2(7) 它仍然会发送一个 datetime 对象并保存它

我遇到了同样的问题,不幸的是,在我的模型上有两个 DateTime 属性,并且在保存更改之前,一个 DateTime 属性是 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; }

模型应该具有可为空的日期时间。应该使用前面建议的检索必须修改的对象的方法,而不是使用 ApplicyPropertyChanges。 在我的例子中,我有这样一个方法来保存我的对象:

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();

[解决]在实体框架代码第一(我的情况)只是改变 DateTimeDateTime?解决我的问题。

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

如果使用实体框架版本 > = 5,则应用[ DatabaseGeneratedOption (DatabaseGeneratedOption。]对类的 DateTime 属性的注释将允许数据库表的触发器执行输入创建记录和更新记录的日期的工作,而不会导致实体框架代码堵塞。

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


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

这与第六个答案相似,由 Dongolo Jeno 写,Gille Q 编辑。

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

没有使用 EF 为 SQL DB 中的 NOT NULL 日期列分配任何值时发生此错误,并通过分配相同的值来解决。

希望这个能帮上忙!

在使用数据库优先方法创建我的类时遇到了这个问题 转换.DateTime (dateCausingproblem) 事实上,总是尝试转换值之前,传递,它保存您从意外的值。

此问题通常发生在尝试更新实体时。例如,您有一个包含名为 DateCreated的字段的实体,该字段是 [需要],当您插入记录时,没有返回错误,但是当您要更新该特定实体时,您将获得

Datetime2转换超出范围错误。

现在解决办法是:

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

例如:

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

将此添加到编辑视图中,您将永远不会出现这种错误,我向您保证。

必须为 date 变量启用 null 值:

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

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

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

 [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.
}

它可能是别的东西,但为未来的读者,检查你的日期时间格式。我有14个月

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

CreateDate 类型为 公共日期时间创建日期

错误 json:

{ “ keyValue”: 1, 「实体」 : { “托德”: 1, “ SysId”: “3730e2b8-8d65-457a-bd50-041ce9705dc6” “允许批准”: 假, “ ApprovalUrl”: 无效, “ ApprovalContent”: 无效, “ IsRead”是真的, “ ExpireTime”: “2020-12-1900:00:00” “ CreateDate”: “0001-01-0100:00:00:00”, “ CreateBy”: 空, “修改日期”“2020-12-189:42:10” “修改方式”: 空, “ UserId”: “ f5250229-c6d1-4210-aed9-1c0287ab1ce3” “ MessageUrl”: “ https://bing.com" ; } }

正确的 json:

{ “ keyValue”: 1, 「实体」 : { “托德”: 1, “ SysId”: “3730e2b8-8d65-457a-bd50-041ce9705dc6” “允许批准”: 假, “ ApprovalUrl”: 无效, “ ApprovalContent”: 无效, “ IsRead”是真的, “ ExpireTime”: “2020-12-1900:00:00” “ CreateDate”: “2020-12-1900:00:00” “ CreateBy”: 空, “修改日期”“2020-12-189:42:10” “修改方式”: 空, “ UserId”: “ f5250229-c6d1-4210-aed9-1c0287ab1ce3” “ MessageUrl”: “ https://bing.com" ; } }