关于有默认值的字段在用EF做插入操作时的思考
2014-09-05 22:17
232 查看
今天在用EF做插入操作的时候发现数据库中一个datetime类型的字段(CreateDate)的值居然全部为null。于是赶紧看表结构发现CreateDate字段居然是允许为空的。
虽然为空,但是设置了默认值getdate(),按说不应该为null的。于是开始测试。
假如一个字段有了默认值,并且又允许为Null,在做插入操作时会发生什么?
如上图中的表结构,CreateDate是允许为null的,而又有默认值getdate()。这样在用传统SQL语句和EF做插入操作时分别会发生什么呢?
先看传统SQL语句:
插入结果:
使用SQL完全没有问题。
再看使用EF:
插入结果:
使用EF插入居然为NULL!!!于是立刻打开SQL Server Profiler监测生成的SQL,EF居然生成了下面的SQL:
没赋值的字段,EF生成SQL的时候居然都置为NULL,管你有没有设默认值!
可能是EF比较娇情,我字段允许为NULL,EF生成SQL时就置为null了。那我把字段设为不允许为NULL,EF又会生成怎样的SQL呢?
这一次CreateDate不允许为NULL了,使用SQL理所当然地一切正常:
那再看下用EF:
结果。。。
”从 datetime2 数据类型到 datetime 数据类型的转换产生一个超出范围的值。“
EF很傲娇地抛了个异常!!为什么会抛出这个异常?这个异常神马意思?于是照妖镜SQL Server Profiler又出场了:
日期类型的字段如果不赋值居然默认给赋值为“0001-01-01 00:00:00”!管你有没有默认值!那也不至于抛异常啊,顶多字段值存储为“0001-01-01 00:00:00”呗。
于是查MSDN发现datetime类型的日期范围仅支持1750-01-01 00:00:00至9999-12-31 23:59:59.997,而0001-01-01 00:00:00不在此范围内,所以抛出异常。原来如此。
datetime和datetime2支持的日期范围如下:
除此之外是否还有别的方法呢?
方法是有的,打开EF的.edmx文件,找到<EntityType Name="表名">节点,把如下节点:
改成:
即可。
虽然为空,但是设置了默认值getdate(),按说不应该为null的。于是开始测试。
字段允许Null值的情况
Users表结构如下:假如一个字段有了默认值,并且又允许为Null,在做插入操作时会发生什么?
如上图中的表结构,CreateDate是允许为null的,而又有默认值getdate()。这样在用传统SQL语句和EF做插入操作时分别会发生什么呢?
先看传统SQL语句:
1 | insert into Users(Username, Password ) values ( 'test' , '123456' ) |
使用SQL完全没有问题。
再看使用EF:
1 2 3 4 5 6 7 | Users user = new Users(); user.Username = "test2" ; user.Password = "123456" ; TestEntities entity = new TestEntities(); entity.Users.Add(user); int result = entity.SaveChanges(); |
使用EF插入居然为NULL!!!于是立刻打开SQL Server Profiler监测生成的SQL,EF居然生成了下面的SQL:
没赋值的字段,EF生成SQL的时候居然都置为NULL,管你有没有设默认值!
可能是EF比较娇情,我字段允许为NULL,EF生成SQL时就置为null了。那我把字段设为不允许为NULL,EF又会生成怎样的SQL呢?
字段不允许Null值的情况
Users表结构如下:这一次CreateDate不允许为NULL了,使用SQL理所当然地一切正常:
1 | insert into Users(Username, Password ) values ( 'admin' , '123456' ) |
那再看下用EF:
1 2 3 4 5 6 7 | Users user = new Users(); user.Username = "admin" ; user.Password = "123456" ; TestEntities entity = new TestEntities(); entity.Users.Add(user); int result = entity.SaveChanges(); |
”从 datetime2 数据类型到 datetime 数据类型的转换产生一个超出范围的值。“
EF很傲娇地抛了个异常!!为什么会抛出这个异常?这个异常神马意思?于是照妖镜SQL Server Profiler又出场了:
日期类型的字段如果不赋值居然默认给赋值为“0001-01-01 00:00:00”!管你有没有默认值!那也不至于抛异常啊,顶多字段值存储为“0001-01-01 00:00:00”呗。
于是查MSDN发现datetime类型的日期范围仅支持1750-01-01 00:00:00至9999-12-31 23:59:59.997,而0001-01-01 00:00:00不在此范围内,所以抛出异常。原来如此。
datetime和datetime2支持的日期范围如下:
结论
如此看来无论字段有没有默认值,使用EF插入时都没有任何实际作用了。因此如果使用你EF建议干脆直接写死算了。比如user.CreateDate = DateTime.Now。除此之外是否还有别的方法呢?
方法是有的,打开EF的.edmx文件,找到<EntityType Name="表名">节点,把如下节点:
<Property Name="CreateDate" Type="datetime" Nullable="false" />
改成:
<Property Name="CreateDate" Type="datetime" Nullable="false" StoreGeneratedPattern="Identity" />
即可。
相关文章推荐
- 关于有默认值的字段在用EF做插入操作时的思考(续)
- 关于有默认值的字段在用EF做插入操作时的思考
- 关于有默认值的字段在用EF做插入操作时的思考
- 关于有默认值的字段在用EF做插入操作时的思考(续)
- 关于有默认值的字段在用EF做插入操作时的思考(续)
- 关于有默认值的字段在用EF做插入操作时的思考
- Hibernate插入和修改数据到数据库中时不修改存在默认值字段
- 使用SSH在做插入和修改的时候即使数据库中给字段设置了默认值还是没有用,在表对应的配置文件中也不知道该如何配置。。请教下。。
- sql2005 若字段定义的类型为datetime,插入为''(空),那么会默认值为1900-01-01 00:00:00.000
- 关于ORACLE当中关于含有关键字作为字段的操作=查询,插入等=规范的双引号操作
- Hibernate插入数据到数据库中时让字段默认值生效
- 关于含有标识字段的数据表中记录的插入问题解决(IDENTITY_INSERT)
- hibernate映射数据库表如何在不插入值的情况下使表中字段默认值生效
- C#中解决插入数据库的某个字段类型为datetime 去掉默认值1900-01-01
- Hibernate插入和修改数据到数据库中时不修改存在默认值字段
- 由小程序引起的思考----关于字段和方法的分派
- 关于在数据库中插入一个单引号括起来的字段问题
- 一些关于 CAD数据库 插入字段
- mySQl建表时怎样才能使datetime型字段默认值为插入值的时刻
- 关于Java读取mysql中date类型字段默认值'0000-00-00'的问题