实体框架EDMX强制DateTime2

时间:2015-01-10 15:10:05

标签: c# sql .net entity-framework edmx

我正在进行一些数据库优化,我发现我的一个主要问题是使用“exec sp_executesql”比使用原始SQL更慢。 我认为这与implicite datetime / datetime2转换有关,因为所有慢查询都是比较日期。

在“exec sp_executesql”的末尾总会出现类似的内容:

)))',N'@p__linq__0 datetime2(7),@p__linq__1 datetime2(7),@p__linq__2 datetime2(7),@p__linq__3 datetime2(7),@p__linq__4 datetime2(7),@p__linq__5 datetime2(7),@p__linq__6 datetime2(7),@p__linq__7 datetime2(7),@p__linq__8 datetime2(7)',@p__linq__0='2015-01-09 18:52:46.9264744',@p__linq__1='2015-01-09 18:52:16.926',@p__linq__2='2015-01-09 18:52:16.926',@p__linq__3='2015-01-09 18:52:16.926',@p__linq__4='2015-01-09 18:52:16.926',@p__linq__5='2015-01-09 18:52:16.926',@p__linq__6='2015-01-09 18:52:16.926',@p__linq__7='2015-01-09 18:52:16.926',@p__linq__8='2015-01-09 18:52:16.926';

在我的数据库中,.NET DateTime存储为datetime。 我的模型是从我的EDMX生成的。

这是我的问题,我应该更改所有日期时间字段,还是可以避免这种无用的隐含转换?

谢谢!

1 个答案:

答案 0 :(得分:1)

我可以确认这种行为(EF 6.1.0)。问题是EF翻译查询阻止SQL服务器使用索引(如果您的DateTime列被索引)。 例如:

exec sp_executesql N'... WHERE ([Extent1].[Timestamp] >= @p__linq__0) AND ([Extent1].[Timestamp] <= @p__linq__1)',N'@p__linq__0 datetime2(7),@p__linq__1 datetime2(7)',@p__linq__0='2014-03-01 0:00:00',@p__linq__1='2015-03-01 0:00:00'

注意查询条件(datetime)和参数datatype(datetime2)之间的区别。

快速解决方法是将DateTime参数声明为可为空,这会为已翻译的查询条件添加额外的CAST,并使用索引。

exec sp_executesql N'...WHERE ( CAST( [Extent1].[Timestamp] AS datetime2) >= @p__linq__0) AND ( CAST( [Extent1].[Timestamp] AS datetime2) <= @p__linq__1)',N'@p__linq__0 datetime2(7),@p__linq__1 datetime2(7)',@p__linq__0='2014-03-01 0:00:00',@p__linq__1='2015-03-01 0:00:00'

这应该在6.1.2修正,没有时间确认。