2014-10-28 100 views
1

我在开发C#程序的Visual Studio 2012中使用实体框架。我想在我的数据库表中添加记录。记录(对象)包含一个属性(TRANSACTION_DATE),该属性不允许NULL值并且是DateTime格式。在数据库中我的目标格式为:将datetime2数据类型转换为日期时间数据类型导致超出范围值

yyyy-MM-dd HH:mm:ss.fff

,所以我想通过当前的日期和时间吧,我的代码是这样的:

newEntry.TRASACTION_DATE = DateTime.ParseExact(DateTime.Now.ToString(), 
          "yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture); 

,但它给我的错误:

The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value.

我想知道为什么它不会转换为我想要的格式?

约束: enter image description here

enter image description here

+2

为什么要将'DateTime.Now'转换为字符串,然后再返回?只需使用'DateTime.Now' ...并注意数据库值不会具有*本质上的格式 - 将其转换为字符串时使用的格式与存储的内容无关。 – 2014-10-28 13:20:05

+0

,因为它不是我想要的格式 – lcc 2014-10-28 13:20:31

+0

我发现这些'日期时间超出范围'的例外几乎总是下到试图在数据库中存储'01 -01-0001 00:00:00',检查SQL被发送到DB – paul 2014-10-28 13:21:26

回答

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真的不应该超出范围,除非你已经应用了单独的约束,或者你的系统时钟在几英里外。

+0

我首先使用了这种方式,它给了我同样的错误。 – lcc 2014-10-28 13:26:41

+0

@lcc:如果你能告诉我们更多关于你的模式等信息,这将会有所帮助。它应该是绝对好的。你的数据库字段是否有其他限制?它可能是由数据库自动填充的吗? – 2014-10-28 13:28:11

+0

@lcc:看看我编辑的答案是否有另一种可能性 - 我想知道它是不是完全不同的领域。错误消息*说*哪个值超出范围?你的数据库表有多少个日期/时间字段? – 2014-10-28 13:30:26

1

DateTime是无关的格式。演示文稿格式就像你所拥有的只是用于显示目的。没有必要将DateTime转换为字符串,然后使用自定义格式进行解析。只需简单地分配DateTime您现场,如:

newEntry.TRASACTION_DATE = DateTime.Now; 

DateTime在SQL Server中有一系列January 1, 1753, through December 31, 9999您解析的代码产生比一年1753一个DateTime值少的,这就是为什么你所得到的例外。

+0

我使用这个,并在开始时给了我相同的错误,这就是为什么我想将它转换为我想要的格式。 – lcc 2014-10-28 13:21:47

+0

@lcc,DB中'TRANSACTION_DATE'的数据类型是什么? – Habib 2014-10-28 13:23:10

+0

日期时间格式@Habib – lcc 2014-10-28 13:24:23

0

您可以将数据库中的列类型切换为datetime2?这是Microsoft's recommendation。某些.Net datetime值不适合datetime,而datetime2类型可以容纳所有.Net datetimes(并且不会通过例如将2010-05-05 23:59:59.999舍入到2010-05-06)引入微妙的错误。

请注意,与datetime不同,将datetime2视为整数(例如,通过执行诸如mydate+1之类的操作)是不合法的。

如果切换到datetime2不是选项,请配置您的ORM代码以明确将此日期视为datetime而不是datetime2。这不会解决你的错误,但它会在你发送查询之前而不是之后导致验证失败,从而更容易修复。

无论您选择什么,都不要使用字符串转换来解决此问题;这是一种黑客,会导致比解决问题更多的问题。

+0

它说我必须删除表或重新创建表来将列类型更改为datetime2。我不能那样做。 – lcc 2014-10-28 15:12:52

+0

我如何配置ORM代码来明确将日期视为日期时间? – lcc 2014-10-28 15:13:16

+0

@lcc:在我自己的测试过程中,如果您通过T-SQL而不是通过SMSS界面更改列(条件限制的东西当然会干扰),则不需要删除表来更改列类型,但请验证这你自己在一个测试数据库。至于更改ORM代码,我不知道你在使用什么ORM。在'SqlParameter'的情况下,您可以将'DbType'设置为'System.Data.DbType.DateTime'。 – Brian 2014-10-28 16:02:27

相关问题