我在Visual Studio 2012中使用Entity Framework开发C#程序。我想在我的数据库表中添加记录。记录(对象)包括一个不允许NULL值的属性(TRANSACTION_DATE),它是一个DateTime格式。在数据库中,我的目标是这种格式:
yyyy-MM-dd HH:mm:ss.fff
所以我想将当前日期和时间传递给它,我的代码是这样的:
newEntry.TRASACTION_DATE = DateTime.ParseExact(DateTime.Now.ToString(),
"yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture);
但它给了我错误:
将datetime2数据类型转换为日期时间数据类型 导致了超出范围的价值。
我想知道为什么它没有转换为我想要的格式?
约束:
答案 0 :(得分:2)
您根本不应该将数据库视为以特定字符串格式存储值 - 除了将数字存储为十进制或十六进制之外。
相反,您应该将其视为日期/时间,例如
// TODO: Do you really want the local time, rather than UtcNow?
// TODO: Change TRANSACT_DATE to be TransactionDate ideally, to follow
// .NET naming conventions
newEntry.TRANSACT_DATE = DateTime.Now;
当您检索该值时,您也应该获得DateTime
。 然后如果要向用户显示值,您可以应用特定格式。不同的用户可能想要不同的格式 - 甚至可能希望在不同的时区显示相同的日期/时间。
区分您存储的内部数据(在本例中为日期/时间)和恰好用于显示任何特定上下文/应用程序的文本格式非常重要。当你不真正需要时,你应该避免在字符串中转换。理想情况下,这些只应位于您的应用程序的边界 - 例如向用户显示文本或可能序列化为JSON或XML时。每当API允许您不执行转换时(例如使用数据库参数),您应该避免使用它。
至于您当前的错误 - 它是否可能是您未填充的不同字段,因此使用default(DateTime)
哪个字段超出范围?这很有道理 - 而DateTime.Now
确实不应该超出范围,除非您已经应用了单独的约束,或者您的系统时钟已经数英里外。
答案 1 :(得分:1)
DateTime
与格式无关。您所拥有的演示文稿格式仅用于显示目的。无需将DateTime
转换为字符串,然后使用自定义格式对其进行解析。只需将DateTime
分配给您的字段,例如:
newEntry.TRASACTION_DATE = DateTime.Now;
SQL Server中的 DateTime
的范围为January 1, 1753, through December 31, 9999
您的解析代码导致DateTime
值低于年1753
,这就是您获得异常的原因。
答案 2 :(得分:0)
您可以将数据库中的列类型切换为datetime2
吗?这是Microsoft's recommendation。一些.Net datetime
值不适合datetime
,而datetime2
类型可以容纳所有。datetimes
(并且不会引入微妙的错误例如,将2010-05-05 23:59:59.999
四舍五入到2010-05-06
)。
请注意,与datetime
相比,将datetime2
视为整数(例如,通过执行mydate+1
之类的操作)是不合法的。
如果无法切换到datetime2
,请将您的ORM代码配置为明确将此日期视为datetime
而非datetime2
。这不会修复您的错误,但是在您发送查询之前而不是之后会导致验证失败,从而使修复更容易。
无论您的选择如何,都不要使用转换为/来自字符串来解决此问题;这是一个导致问题多于解决问题的黑客攻击。