如何修复“SqlException:将datetime2数据类型转换为datetime数据类型导致超出范围的值。”

23

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

我的代码是这样的:

        using (var contxt = new realtydbEntities())
        {
            var status = GetStatus();

            var repIssue = new RepairIssue()
            {
                CreaterId = AuthorId,
                RepairItemDesc = this.txtDescription.Text,
                CreateDate = DateTime.Now,//here's the problem
                RepairIssueStatu = status
            };

            contxt.AddObject("RepairIssues", repIssue);
            contxt.SaveChanges();
        }

CreateDate 属性映射到一个类型为 smalldatetime 的列上,如何使得这段代码运行?


6个回答

22

我遇到了同样的异常,但是原因是一个非空日期时间属性取到了最小的日期时间值。在数据库中并不是一个smalldatetime类型,而是C#中最小日期时间值超过SQL的最小日期时间限制。 解决方法很明显,正确设置日期时间。 顺便说一下,这段代码不是我的,所以我不知道那个属性是什么 :)


2
你是如何正确设置日期时间的? - Hoang Minh
最后一句话中的注释很可爱 :) - Alex P.

11
你的问题根源在于C#的DateTime对象比SQL的smalldatetime类型“更大”。这里有一个很好的概述介绍了它们之间的区别:http://karaszi.com/the-ultimate-guide-to-the-datetime-datatypes 因此,你真正的选择是:
  1. 将列类型从smalldatetime更改为datetime(或datetime2)
  2. 不使用EF,自己构建SQL命令(可以使用SqlDateTime)

3
这并不解释为什么 DateTime.Now 无法适应 SmallDateTime。这与大小关系不大,而与其可存储的范围、精度和准确性有关。DateTime.Now 应该始终是 SmallDateTime 字段的有效值(除非您将 PC 时钟往回调了300年),但是我现在尝试将 {04/10/2013 12:49:00} 的 'DateTime.Now' 值简单保存到 SQL SmallDateTime 字段中也遇到了完全相同的错误。真让人沮丧的是,在任何 SO 上都找不到正确的答案。 - iCollect.it Ltd
@TrueBlueAussie 自动将“较大”类型转换为“较小”类型是不允许的,因为在转换过程中可能会丢失信息。无论“较大”是否意味着“可以容纳更大的数字”或者是否意味着“可以容纳更多的精度”,这都是同样适用的。C#假定这些小数秒很重要,除非您明确表示它们不重要(例如,使用显式转换)。 - GrandOpener
@GrandOpener:抱歉,你误解了我的评论。我只是想说这个答案应该解释为什么dateTime.Now不适合于SmallDateTime。我并没有要求解释 :) - iCollect.it Ltd

3

将以下内容添加到您的模型类中:

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

1

如果按照您的建议从 DateTime 创建一个 SqlDateTime,然后将其 Value 用于 EF 更新(因为 EF 属性是 DateTime),则仍然会出现完全相同的错误(如果您遇到了这个错误)。除非您能够澄清如何解决此问题,否则此答案对于 EF(该问题所涉及的内容)似乎是不正确的。 - iCollect.it Ltd

0

请检查您的迁移内容。我将我的模型更改为以下内容:

public DateTime? CreationDate { get; set; }

然后添加新的迁移,最后运行更新数据库。


0
我遇到了这个错误,因为我在不删除旧数据的情况下向我的SQL表和应用程序中添加了一个日期时间列。我发现我可以更新新记录;但是,在添加字段之前存在于表中的记录在尝试更新其中一个记录时会引发此错误。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接