2010-07-15 56 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;