2010-10-22 71 views
1

以下LINQ to SQL查询将日期分成多个部分。日期比较使用下面生成的SQL语句似乎很奇怪。从LINQ到SQL生成的T-SQL执行DATEPART

var customers = 
(from c in db.customers 
where c.servhists.Any(sh => sh.donedate.Value.Date >= startDate.Date 
       && sh.donedate.Value.Date <= endDate.Date 
       && sh.donedate.Value.AddDays(triggerDays).Date <= DateTime.Now.Date) 

产生以下SQL查询MS SQL Server 2008的

...

WHERE (DATEADD(HOUR, -DATEPART(HOUR, [t3].[donedate]), DATEADD(MINUTE, -DATEPART(MINUTE, [t3].[donedate]), DATEADD(SECOND, -DATEPART(SECOND, [t3].[donedate]), DATEADD(MILLISECOND, -DATEPART(MILLISECOND, [t3].[donedate]), [t3].[donedate])))) >= '6/7/2010') AND (DATEADD(HOUR, -DATEPART(HOUR, [t3].[donedate]), DATEADD(MINUTE, -DATEPART(MINUTE, [t3].[donedate]), DATEADD(SECOND, -DATEPART(SECOND, [t3].[donedate]), DATEADD(MILLISECOND, -DATEPART(MILLISECOND, [t3].[donedate]), [t3].[donedate])))) <= '8/8/2010') AND (DATEADD(HOUR, -DATEPART(HOUR, DATEADD(ms, (CONVERT(BigInt,3 * 86400000)) % 86400000, DATEADD(day, (CONVERT(BigInt,3 * 86400000))/86400000, [t3].[donedate]))), DATEADD(MINUTE, -DATEPART(MINUTE, DATEADD(ms, (CONVERT(BigInt,3 * 86400000)) % 86400000, DATEADD(day, (CONVERT(BigInt,3 * 86400000))/86400000, [t3].[donedate]))), DATEADD(SECOND, -DATEPART(SECOND, DATEADD(ms, (CONVERT(BigInt,3 * 86400000)) % 86400000, DATEADD(day, (CONVERT(BigInt,3 * 86400000))/86400000, [t3].[donedate]))), DATEADD(MILLISECOND, -DATEPART(MILLISECOND, DATEADD(ms, (CONVERT(BigInt,3 * 86400000)) % 86400000, DATEADD(day, (CONVERT(BigInt,3 * 86400000))/86400000, [t3].[donedate]))), DATEADD(ms, (CONVERT(BigInt,3 * 86400000)) % 86400000, DATEADD(day, (CONVERT(BigInt,3 * 86400000))/86400000, [t3].[donedate])))))) <= '10/22/2010') 

.. donedate是DateTime类型的空列

我不能想象这有助于提高性能。任何人都可以提出一个修复/更正,我可以做摆脱这个丑陋的SQL?

回答

1

您看到生成的SQL是由LINQ如何将列上的Date属性的使用呈现为SQL的结果。更改日期数学以避免在列本身上使用Date属性和其他日期操作。相反,请尽可能多地对日期数学运算进行操作,以便在与列对比的变量上进行操作。

var customers = (from c in db.customers 
       where c.servhists.Any(sh => sh.donedate.Value >= startDate.Date 
             && sh.donedate.Value < endDate.Date.AddDays(1) 
             && sh.donedate.Value <= DateTime.Now.AddDays(0 - triggerDays).Date) 

这可能需要进一步调整,以便在切换之前比较已知的结果。这应该足以给你这个想法。

+0

这可能会返回所有结果在一百万行的表中,然后才能将它们滤除。 – 2012-03-03 14:00:36

+1

其实不,这就是要点。如果您在对您所比较的变量而不是列进行操作时进行了等效计算,则仍然会对其进行过滤。我会更新答案,以包括我正在谈论的一个例子。 – JamieSee 2012-03-06 18:13:20

+0

感谢您的澄清。我现在看到你的意思是什么......它是有道理的不修改SQL日期时间。 – 2012-03-06 22:19:08