Asp.net 错误-SqlDateTime溢出。必须在1753年1月1日12:00:00 AM和9999年12月31日11:59:59 PM之间

Asp.net 错误-SqlDateTime溢出。必须在1753年1月1日12:00:00 AM和9999年12月31日11:59:59 PM之间,asp.net,linq-to-sql,sql-server-2008,Asp.net,Linq To Sql,Sql Server 2008,我一直在使用我写的这段代码,它以这种最不清楚的方式工作。我希望在数据库中插入一行,其中包含两列DateTime: myrow.ApprovalDate = DateTime.Now myrow.ProposedDate = DateTime.Now 然而,当我更新数据库时,我收到以下错误: SqlDateTime溢出。必须在1753年1月1日12:00:00 AM和9999年12月31日11:59:59 PM之间 我甚至尝试过从数据库复制插入值,并将其硬编码到正在更新的对象中: // I co

我一直在使用我写的这段代码,它以这种最不清楚的方式工作。我希望在数据库中插入一行,其中包含两列DateTime:

myrow.ApprovalDate = DateTime.Now
myrow.ProposedDate = DateTime.Now
然而,当我更新数据库时,我收到以下错误:

SqlDateTime溢出。必须在1753年1月1日12:00:00 AM和9999年12月31日11:59:59 PM之间

我甚至尝试过从数据库复制插入值,并将其硬编码到正在更新的对象中:

// I copied this value from the DB
myrow.ApprovalDate =  Convert.ToDateTime("2008-12-24 00:00:00.000");

还是同一个错误,奇怪的是,上面的技巧在第一次插入DB时起作用,但从那以后就失败了。知道发生了什么吗?

这通常意味着向查询传递的是null而不是您想要的值,您可以尝试运行SQL事件探查器,以查看从linq传递到SQL Server的确切内容。

这两列的代码看起来正常。在该映射类上查找任何其他datetime列。另外,在datacontext上启用日志记录以查看查询和参数

dc.Log = Console.Out;
DateTime初始化为c#的0,即0001-01-01。这由linqtosql通过sql字符串文字“0001-01-01”传输到数据库。Sql无法从此日期解析T-Sql日期时间

有几种方法可以解决这个问题:

  • 确保使用SQL可以处理的值(例如SQL的0:1900-01-01)初始化所有日期时间
  • 确保任何偶尔被忽略的日期时间都是可为空的

C#中的A
DateTime
是值类型,而不是引用类型,因此不能为null。但是,它可以是常量
DateTime.MinValue
,它不在Sql Server
DateTime
数据类型的范围内

值类型保证始终具有(默认)值(零),而无需始终显式设置(在本例中为DateTime.MinValue)

结论是您可能有一个未设置的DateTime值,您正试图传递给数据库

DateTime.MinValue = 1/1/0001 12:00:00 AM
DateTime.MaxValue = 23:59:59.9999999, December 31, 9999, 
                    exactly one 100-nanosecond tick 
                    before 00:00:00, January 1, 10000
MSDN:


关于Sql Server

日期时间
1753年1月1日至9999年12月31日的日期和时间数据,精确到百分之一秒(相当于3.33毫秒或0.00333秒)。值四舍五入为.000、.003或.007秒的增量

smalldatetime
1900年1月1日至2079年6月6日的日期和时间数据,精确到分钟。小于等于29.998秒的smalldatetime值向下舍入到最接近的分钟;29.999秒或更高的值向上舍入到最接近的分钟

MSDN:


最后,如果您发现自己将一个C#
DateTime
作为字符串传递给sql,则需要按如下方式对其进行格式化,以保持最大精度并防止sql server引发类似错误

string sqlTimeAsString = myDateTime.ToString("yyyy-MM-ddTHH:mm:ss.fff");

更新(8年后)

考虑使用sql
DateTime2
数据类型,该数据类型与.net
DateTime
的日期范围
0001-01-01到9999-12-31
和时间范围
00:00:00到23:59:59.999999

string dateTime2String = myDateTime.ToString("yyyy-MM-ddTHH:mm:ss.fffffff");

MSDN

有时为了编写更少的代码,SQL server在插入时通过将字段的默认值设置为
GETDATE()
NEWID()
来设置日期、时间和ID等字段

在这种情况下,实体类中这些字段的自动生成值应设置为true


通过这种方式,您不需要在代码中设置值(防止能耗!!!),也不会看到异常情况。

我发现,在出现许多与数据库相关的错误后,使用以下方法可以很好地处理SQL最小/最大日期:

DateTime rngMin = (DateTime)System.Data.SqlTypes.SqlDateTime.MinValue;

DateTime rngMax = (DateTime)System.Data.SqlTypes.SqlDateTime.MaxValue;

如果您使用的是NHibernate,请检查是否在映射中将适当的可为null的DateTime属性设置为可为null。

在将.Net DateTime与SqlDateTime.MinValue或MaxValue进行比较时要小心。例如,以下内容将引发异常:

DateTime dte = new DateTime(1000, 1, 1);
if (dte >= SqlDateTime.MinValue)
    //do something
原因是MinValue返回的是SqlDateTime,而不是DateTime。因此.Net尝试将dte转换为SqlDateTime进行比较,因为它超出了可接受的SqlDateTime范围,所以抛出异常


解决这个问题的一个方法是将DateTime与SqlDateTime.MinValue进行比较。Value

我看到了同样的情况。该错误不会在插入行时发生,而是在更新时发生。我引用的表有两个DateTime列,它们都不可为空

我将场景简化为获取行并立即保存它(无数据更改)。get工作正常,但更新失败


我们使用的是NHibernate 3.3.1.4000

通常在进行日期时间转换或解析时会出现这种错误。检查应用程序所在服务器中的日历设置,主要是时区和短日期格式,并确保将其设置为位置的正确时区。希望这能解决问题。

DateTime.MinValue和DateTime.MaxValue

DateTime.MinValue = 1/1/0001 12:00:00 AM

DateTime.MaxValue = 23:59:59.9999999, December 31, 9999, 

                exactly one 100-nanosecond tick 

                before 00:00:00, January 1, 10000 

如果试图将DateTime类型的变量设置为null,则会发生此错误。将变量声明为可空,即DateTime?。这将解决问题。

使用扩展方法

 public static object ToSafeDbDateDBnull(this object objectstring)
    {
        try
        {
            if ((DateTime)objectstring >= SqlDateTime.MinValue)
            {
                return objectstring;
            }
            else
            {
                return DBNull.Value;
            }
        }
        catch (Exception)
        {

            return DBNull.Value;
        }

    }

DateTime objdte = new DateTime(1000, 1, 1);
dte.ToSafeDbDateDBnull();

如果在模型中像
Datetime?
一样将Datetime设置为null,则不会引发异常


在我的例子中,我解决了这样的问题。

在我的例子中,由于table date列不能为null,所以出现了此错误

 Create Table #TempTable(
 ...
 ApprovalDate datatime null.
 ...)
详情如下:

Create Table #TempTable(
 ...
 ApprovalDate datatime not null.
 ...)
要避免此错误,只需将其设为空即可

 Create Table #TempTable(
 ...
 ApprovalDate datatime null.
 ...)

发布你的代码。此外,您可以考虑只检查LINQ正在构建的内容。我通常使用1970-01-01,这是计算机时间的一个常见时期(UNIX TimeTyt和JavaScript),感谢将日志重定向到控制台的提示。OUT。感谢指针>代码> DATETIME/<代码>不能在C*中无效!这应该得到最多的选票,也是正确的答案