如何更改Entity Framework为Datetime生成SQL精度的方式
我有一个表使用id和DateTime列是pk,但当我尝试按entity framework更新数据时,如下所示:
using (Entities context = new Entities()) { var item = (from item in context.BatchData where item.Id == 2 select item ).FirstOrDefault(); item.Title = "EF6TEST"; context.SaveChanges(); }
我收到一个错误
存储更新,插入或删除语句会影响意外的行数(0)。
记录SQL后,我知道原因。
SQL看起来像这样
'update [dbo].[BatchData] set [BatchData_Title] = @0 where (([BatchData_Id] = @1) and ([BatchData_CreatedDateTime] = @2)) select [BatchData_Rowversion] from [dbo].[BatchData]BatchUploadData where @@ROWCOUNT > 0 and [BatchData_Id] = @1 and [BatchData_CreatedDateTime] = @2', N'@0 varchar(30),@1 tinyint,@2 datetime2(7)', @0='EF6TEST',@1=1,@2='2017-09-16 11:29:35.3720000'
所以,原因是SQL中的BatchData_CreatedDateTime
参数是@2='2017-09-16 11:29:35.3720000'
,精度是7,它应该是@2='2017-09-16 11:29:35.372'
。
这是我的问题,如何解决?
您可以使用IDbInterceptor
来更改所需的数据,这里是一个拦截器的示例,它将参数类型从DateTime2
更改为DateTime
,您可以扩展它以在DB / DbCommand参数的特定字段上使用它。
public class DateInterceptor : IDbInterceptor, IDbCommandInterceptor { public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext interceptionContext) { var dateParameters = command.Parameters.OfType() .Where(p => p.DbType == DbType.DateTime2); foreach (var parameter in dateParameters) { parameter.DbType = DbType.DateTime; } }
要使用它,请添加DbInterception.Add(new DateInterceptor());
到您的dbContext类的OnModelCreating
结束
生成的SQL将从中更改
@ 2 datetime2(7)’,@ 0 = 0,@ 1 = 1,@ 2 =’2017-09-24 14:41:33.7950485′
至
@ 2 datetime’,@ 0 = 0,@ 1 = 1,@ 2 =’2017-09-24 14:40:32.327′
我认为这是SQL 2016或Azure SQL数据库。
请参阅此SO问题entity framework格式化DateTime SQL参数,不带毫秒,以实现乐观并发
SQL 2016改变了datetime和datetime2之间转换的工作方式。 要使用乐观并发,最好使用datetime2(7)。