将datetime2数据类型转换为smalldatetime数据类型导致值超出范围。\r\n语句已终止。

5

我制作了一个小的MVC4应用程序,并在我的本地SQL 2012服务器上创建了数据库。我将数据从2012“导入”到我的廉价共享主机中作为生产环境,使用的是sql 2008。一切正常。对非aspmembership表进行了一些更改,并从sql 2008中删除了表格并重新导入。现在出现了以下错误:

The conversion of a datetime2 data type to a smalldatetime data type resulted in an out-of-range value.\r\nThe statement has been terminated

如果我尝试注册一个帐户。我尝试将所有的smalldatetime列更改为datetime2列,但出现了相同的错误,即使没有smalldatetime? 有人有什么想法吗?谢谢。
编辑:未来的人们 - 我不确定为什么这样修复了它,但我在SQL Express 2008中重新创建了表,而不是SQL 2012,然后将它们移动过去。工作正常。

这些似乎是相关的:https://dev59.com/knRB5IYBdhLWcg3wV156和https://dev59.com/NG445IYBdhLWcg3w9O7R - daryal
看起来日期在神奇的年份“1753”之前,因此对于“smalldatetime”失败了,你能检查一下导致这个问题的值吗? - V4Vendetta
6
smalldatetime的日期范围为1900-01-01到2079-06-06,而datetime2的日期范围为0001-01-01到9999-12-31。请检查您的任何值是否超出了smalldatetime的范围。您是否有使用smalldatetime变量或具有smalldatetime参数的存储过程或函数? - Mikael Eriksson
1个回答

13

从错误信息看,您的数据库使用SmallDateTime作为日期类型。它的最小值是1900年1月1日。假设您的实体类似于以下内容:

  public class Game
  {
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid GameId { get; set; }

    [Required]
    public DateTime GameTime { get; set; }
  }

您的GameTime值不可为空,因此当您没有为其设置任何值时,它将始终是DateTime.Min,即0000-Jan-01。这超出了SmallDateTime的范围,但在DateTime2的范围内。因此,EF将尝试将DateTime2 SQL类型传递给SQL服务器。由于您的数据库正在使用SmallDateTime,所以您会得到您提问中显示的错误。
要解决此问题,我想到以下选项:
  • 使字段可为空。(您必须始终检查输入日期是否在SmallDateTime范围内。)
  • 或将日期类型更改为SQL Server中的DateTime2。
  • 或强制EF在创建数据库时使用DateTime2数据类型。代码将类似于以下内容。(此方法应位于上下文类内部。)

  protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity()
            .Property(t => t.GameTime )
            .HasColumnType("datetime2");
    }
  • 编写一个转换器助手,将您的DateTime属性最小值设置为与应用程序中的smalldatetime相匹配。

  • 在数据库中编写触发器,将DateTime2(来自应用程序端,但在数据库端为datetime2)转换为smalldatetime。

希望我正确理解了您的问题,并且我的回答有所帮助。


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