我有以下查询:
var data = from d in dc.GAMEs
where (d.GAMEDATE + d.GAMETIME.Value.TimeOfDay) >= DateTime.Now select d;
这会生成一些看起来很像的SQL,看起来像这样:
SELECT {...} WHERE DATEADD(ms, ((CONVERT(BigInt,((CONVERT(BigInt,DATEPART(HOUR, [t0].[GAMETIME]))) * 36000000000) + ((CONVERT(BigInt,DATEPART(MINUTE, [t0].[GAMETIME]))) * 600000000) + ((CONVERT(BigInt,DATEPART(SECOND, [t0].[GAMETIME]))) * 10000000) + ((CONVERT(BigInt,DATEPART(MILLISECOND, [t0].[GAMETIME]))) * 10000))) / 10000) % 86400000, CONVERT(DateTime,DATEADD(day, (CONVERT(BigInt,((CONVERT(BigInt,DATEPART(HOUR, [t0].[GAMETIME]))) * 36000000000) + ((CONVERT(BigInt,DATEPART(MINUTE, [t0].[GAMETIME]))) * 600000000) + ((CONVERT(BigInt,DATEPART(SECOND, [t0].[GAMETIME]))) * 10000000) + ((CONVERT(BigInt,DATEPART(MILLISECOND, [t0].[GAMETIME]))) * 10000))) / 864000000000, [t0].[GAMEDATE]))) >= @p0
这么多SQL的原因是什么?是否有更好的方法来处理它?</ p>
编辑:
我无法控制架构。它就是这样,我必须处理它。
答案 0 :(得分:2)
如果您可以更改架构,那么处理架构的最佳方法是使用单个datetime2
列,而不是单独的date
和time
字段。您当前的查询将无法使用索引。
否则您可以尝试重写查询,如下所示:
DateTime now = DateTime.Now;
var data = from d in dc.GAMEs
where (d.GAMEDATE > now.Date) ||
(d.GAMEDATE == now.Date && d.GAMETIME.Value.TimeOfDay >= now.TimeOfDay)
select d;
此查询生成的SQL可能稍微更具可读性,也可能更高效。另一方面,从程序员的角度来看,源代码的可读性比生成的SQL可读更重要。如果性能不是问题,您可能希望保留代码,只是接受生成的SQL很难看而不用担心。
答案 1 :(得分:0)
作为替代方案(因为最外层的OR是索引的祸根)
DateTime now = DateTime.Now;
DateTime today = now.Date;
TimeSpan timeOfDay = now.TimeOfDay;
var data =
from d in dc.GAMEs
where d.GAMEDATE >= today
&& (d.GAMEDATE > today || d.GAMETIME.Value.TimeOfDay >= timeOfDay)
select d;