关于有默认值的字段在用EF做插入操作时的思考

关于有默认值的字段在用EF做插入操作时的思考

今天在用EF做插入操作的时候发现数据库中一个daletime类型的字段(CreateDate)的值居然全部为nul。于是赶紧看表结构发现CreateDate字段居然是允许为空的。
虽然为空,但是设置了默认值getdate(),按说不应该为null的。于是开始测试。

字段允许Null值的情况

Users表结构如下:

假如一个字段有了默认值,并且又允许为Null,在做插入操作时会发生什么?

如上图中的表结构,CreateDate是允许为null的,而又有默认值getdate()。这样在用传统SQL语句和EF做插入操作时分别会发生什么呢?

先看传统SQL语句;

insert into Users(Username,Password) values("‘test’,“123456”)

插入结果:

使用SQL完全没有问题。

再看使用EF:

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时就置为ntull了。那我把字段设为不允许为NULL,EF又会生成怎样的SQL呢?

字段不允许Null值的情况

Users表结构如下:

这一次CreateDate不允许为NULL了,使用SQL理所当然地一切正常:

insert into Users(Username,Password) values('admin";,'123456")

那再看下用EF:

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 0:00:00",这和生成SQL无关,是在生成SQL之前CLR进行的初始化操作,同理String类 型的字段如果不赋值会给默认值
String. Empty!

但是,那也不至于抛异常啊,顶多字段值存储为0001-01-01 0000呗。

于是查MSDN发现daletime类型的日期范围仅支持1750-01-01 0000关至909 1231 23.5.59.997. 000101-01 000不在此范围内,所以势出景常中原来如此大全
datetime和datetime2支持的日期范围如下:

结论

如此看来无论字段有没有默认值,使用EF插 入时都没有任何实际作用了。因此如果你使用EF建议干脆直接写死算了。比如user.CreateDate = DateTime.Now。

ps.这里只是举个例子,事实上,在实际项目中不建议写成DateTime.Now.因为数据库系统时间和服务器时间一般是不同的,笔者实际项目中其实是封装了一个方法叫
GetSQL ServerSystemDateTime.

除此之外是否还有别的方法呢?

方法是有的,打开EF的.edmx文件, 找到节点,把如下节点:

<Praperty Name=“CreateDate” Type=“datetime” Nullable-“false” />

改成:

<Property Name=“'CreateDate” Type=“datetime” Nulale"fase" StoreGeneratedattern-=“Computed” />

即可。

StoreGeneratedPattern是 -个枚举:

●None -个值,指示它不是服务器生成的属性。这是默认值。如果没有●StoreGeneratedPattern属性,其值就默认为None。
●ldentity 执行插入时生成-一个值, 但在执行更新时保持不变。
●Computed执行插入和更新时都将生成个值。

笔者经过实际测试发现:

1.如果将StoreGeneratedPattern值设置为Identity. 只要-修改CreateDate字段就会抛异常;
2.如果把StoreGeneratedPattern值设置为Computed不会抛异常,但值仍然没有被修改,即使你写了user.CreateDate = “xx”。

所以如果你使用EF,我还是建议采用第一 种方式, 直接在程序中赋值user.CreateDate = xx.GetSQLServerSystemDateTime()。 这种方法省事且安全。修改edmx文件太麻
烦,况且每增加一个datetime类型的字 段都要修改- -次edmx文件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值