Asp.net 错误-SqlDateTime溢出。必须在1753年1月1日12:00:00 AM和9999年12月31日11:59:59 PM之间
我一直在使用我写的这段代码,它以这种最不清楚的方式工作。我希望在数据库中插入一行,其中包含两列DateTime: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
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)初始化所有日期时间
- 确保任何偶尔被忽略的日期时间都是可为空的
DateTime
是值类型,而不是引用类型,因此不能为null。但是,它可以是常量DateTime.MinValue
,它不在Sql ServerDateTime
数据类型的范围内
值类型保证始终具有(默认)值(零),而无需始终显式设置(在本例中为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
数据类型,该数据类型与.netDateTime
的日期范围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*中无效!这应该得到最多的选票,也是正确的答案