2010-10-22 26 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