2010-07-15 89 views
2

我有以下查询:如何从LINQ2SQL查询更好的SQL

var data = from d in dc.GAMEs 
    where (d.GAMEDATE + d.GAMETIME.Value.TimeOfDay) >= DateTime.Now select d; 

这会产生一些horendous寻找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的数量?有没有更好的方法来处理它?

编辑:

我无法控制架构。它就是这样,我必须处理它。

回答

2

如果您可以更改架构,那么处理它的最佳方法是使用单个datetime2列而不是单独的datetime字段。您当前的查询将无法使用索引。

否则,你可以尝试重写查询,如下所示:

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很丑并且不用担心它。

+0

我很想,但不能。它会打破我们没有来源的现有应用程序。 – 2010-07-15 21:37:58

+0

@Mystere Man:您是否考虑过将datetime2添加为计算列?如果你坚持下来,你甚至可以索引它。在不更改任何现有列的情况下添加额外的列有相当好的机会不会破坏现有的应用程序(尽管您需要彻底测试它)。 http://msdn.microsoft.com/en-us/library/ms191250.aspx – 2010-07-15 21:46:13

+0

我的假设是,由于生成的SQL中的所有计算,它会明显变慢。不,我没有测量这个,Knuth引用到一边,我更喜欢清理sql。 – 2010-07-15 21:49:53

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;