从LINQ到SQL生成的T-SQL执行DATEPART

时间:2010-10-22 17:55:14

标签: .net linq-to-sql

以下LINQ to SQL查询将日期拆分为多个部分。似乎奇怪的是,日期比较将使用以下生成的SQL语句。

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)

为MS SQL Server 2008生成以下SQL查询

...

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 个答案:

答案 0 :(得分: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)

这可能需要进一步调整,以便在切换前比较您所知道的结果。这应该足以让你有这个想法。