在一个访问下位机的程序中,返回的时间戳有时候因断线产生0001年01月01日的时间,而原先使用拼接SQL进行数据存储的操作时,这个问题是可以跳过的。

这次把拼接SQL的部分重新改为EF进行管理,这个坑就不能避免了。

datetime2是个什么鬼?

datetime2 是一个在范围和精度上都优于 datetime 类型的时间类型。

传统的datetime类型,时间的最小值是 1753-01-01,精度最多到秒后三位。这也是被大家所熟知的时间类型。在今天的多数业务下,这个时间在使用上没有什么问题。

但是总有些不那么和谐的玩艺,居然总想搞个大新闻,用时间类型来标志异常(其实也没什么问题,毕竟异常了未必有时间戳,那么空的时间戳就出现了)

于是,时间的Null怎么表示呢?多数的策略选择了 0001-01-01 00:00:00这样一个时间。毕竟比起大家都知道的 1753-01-01,这个公元元年第一天的时间更具有标志意义。

但是传统那个Datetime它记不了这个值啊。

所以,一个更长、更细(好像哪里不对的样子)的datetime2类型出现了。 这个类型其实也基本被各个语言都实现了,所以算是一个标准。只是大多数程序员在很长的职业生涯里未必真的遇到这种情况,所以并不被多数人熟知。

那么,报错的实际情况是什么呢?

System.Data.SqlClient.SqlException: 从 datetime2 数据类型到 datetime 数据类型的转换产生一个超出范围的值.

这个其实有点误导性质。

这个转换实质上是EF内部完成的。在EF创建了DB First的Model后,正常情况下,相关的这个映射字段的类型依然和数据库设计保持一致,是datetime。 但是,在赋值的过程中,如果这个字段没有赋值、或者赋值给出了0001-01-01的时间(或者小于1753的时间),结果就是EF会根据表的设计约束(显然就是字段必填了)转换成一个实质上的datetime2类型。(确实这个类型没办法自己声明出来啊,所以这应该算一个坑)

然后,接下来的故事就必然发生了,在EF执行 db.SaveChanges()操作时,数据库只接受datetime类型的日期,而不接受datetime2类型的值。进而就抛出这样一个错误。

so?解决方案呢?

显然,最直接的解决策略是改数据表的字段为 datetime2类型。 这个是支持的,所以没有什么大问题。当然后果就是,如果进行一个按时间正序进行的查询,那么肯定会有大量的0001-01-01的数据出现。在多数业务系统中,这种数据应该直接判定为错数而丢弃。

稍好的方案是对代码中的datetime设置为 Nullable 类型,允许空。 相比之下,这个做法更优雅一些,程序的逻辑更直观。

当然,也有一些算是奇淫技巧的方案,酌情吧:

  1. 在C#中用new DateTime(year,month,day,hour,minute,second)来限制精度
  2. 这个方法不太推荐,将model的edmx中的providerManifestToken设置成2005,这样ef就默认转化成datetime

个人觉得,这俩方案并不和谐。其一,需要在时间类型上作不少限制,其二,这样修改配置的思路基本上是只解决当前问题,不顾其他影响的思路。

在我的实际案例里,因为这个值需要作为标记异常的用途,所以在不修改前一个版本的底层的要求下,暂时给设置成1753-01-01确保兼容,在全新部署的版本上再进一步利用这个标志。

EF6中一个关于时间类型 datetime2 的坑的更多相关文章

  1. MySQL 中常见的时间类型有三种 DATE, DATETIME 和 TIMESTAMP

    MySQL 中常见的时间类型有三种 DATE, DATETIME 和 TIMESTAMP,其中 DATE 类型用于表示日期,但是不会包含时间,格式为 YYYY-MM-DD,而 DATETIME 和 T ...

  2. PHPExcel对于Excel中日期和时间类型的处理

    PHPExcel是一款优秀的处理Excel文件读写的开源PHP Library,能够给我们提供强大的Excel读写能力,本文针对Excel处理过程中关于日期和时间类型的处理进行深入的讨论.PHPExc ...

  3. MySQL 中的日期时间类型

    日期时间类型中包含以下几种数据类型: DATE TIME DATETIME TIMESTAMP YEAR 各类型都有具体的取值范围,超出或非法的其他值时,MySQL 会回退到 0.TIMESTAMP ...

  4. MySQL中日期和时间类型

    1 日期类型 MySql中关于日期的类型有Date/Datetime/Timestamp三种类型. 日期赋值时,允许"不严格"语法:任何标点符都可以用做日期部分或时间部分之间的间割 ...

  5. Ext如何Gird中如何显示时间类型的列?

         rt,后台bean中的字段属性是Date类型,前台的model中的字段属性也设置为date类型,但是还是显示不出来,如何解决呢? 直接代码: grid中的COLUMN: Model中的定义:

  6. MySQL中日期与时间类型

    http://blog.sina.com.cn/s/blog_4d8730df01014jiy.html

  7. oracle中两个时间类型的数据相减默认得到的是天数。

    想要得到月份数,需要使用months_between函数. months_between(to_date('201707','yyyyMM'),to_date('201706','yyyyMM'))  ...

  8. 「Flink」Flink中的时间类型

    Flink中的时间类型和窗口是非常重要概念,是学习Flink必须要掌握的两个知识点. Flink中的时间类型 时间类型介绍 Flink流式处理中支持不同类型的时间.分为以下几种: 处理时间 Flink ...

  9. SQL Server的日期和时间类型

    Sql Server使用 Date 表示日期,time表示时间,使用datetime和datetime2表示日期和时间. 1,秒的精度是指使用多少位小数表示秒 DateTime数据类型秒的精度是3,D ...

随机推荐

  1. “程序包com.sun.tools.javac.util不存在” 问题解决

    最近工作中在编译打包项目的时候遇到了如标题所示的问题,报这个错误的类是 com.sun.tools.javac.util.Pair.问题很诡异,在Idea可以导入此类,项目启动运行也很正常,但就是在打 ...

  2. luogu P5329 [SNOI2019]字符串

    传送门 显然要写一个排序,那只要考虑cmp函数怎么写就行了.第\(i\)个字符串和第 \(j\)个,首先前\(min(i,j)-1\)个字符是相同的,然后就是要比较后缀\(min(i,j)\)和\(m ...

  3. http参数传递方式

    url传参 这种在各种method(get,post,delete,put)都能使用,解析速度快 body体中的参数 application/x-www-form-urlencoded 这应该是最常见 ...

  4. [七月挑选]Tomcat使用命令行启动之指定jdk版本

    title: Tomcat使用命令行启动之指定jdk版本 准备好环境,jdk和tomcat. 主要步骤 1.找到Tomcat/bin/catalina.bat文件. 2.在文件前端添加如下. set ...

  5. Tomcat报java.io.IOException: Broken pipe错误

    Tomcat报java.io.IOException: Broken pipe错误,如下图: 解决方案:我的原因是因为网络策略导致出现该问题,即网络端口未启用或被限制.

  6. SVN服务之VisualSVN-Server和TortoiseSVN

    SVN客户端程序:TortoiseSVN SVN服务器程序:VisualSVN-Server   目前有个项目,需要版本服务器,由于习惯了svn的使用,让这边搭建一台svn服务器,做了一下整理,只满足 ...

  7. 闲着没事写点啥之springmvc梳理

    用户通过浏览器向服务器发送请求,请求被springmvc的前端控制器dispatcherservlet拦截. dispatcherservlet拦截到请求后,会调用handlermapping处理器映 ...

  8. Java动手动脑02

    一.平方数静方法: public class SquareInt { public static void main(String[] args) { int result; for (int x = ...

  9. ==和is的区别 以及编码和解码

    is和==的区别 1. id() id是python的一个内置函数,通过id()可以查看变量表的值在内存中的地址. s1 = 2 print(id(s1)) # 1514368064 s2 = 2 p ...

  10. Python---进阶---捕获异常

    一.编写一个计算减法的方法,当第一个数小于第二个数时,抛出“被减数不能小于减数”的异常 ------------------------------------------------- def ji ...