Как сгенерировать лучший SQL из запроса Linq2Sql - PullRequest
2 голосов
/ 16 июля 2010

У меня следующий запрос:

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

Это генерирует какой-то ужасно выглядящий 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? И есть ли лучший способ справиться с этим?

EDIT:

У меня нет контроля над схемой. Это то, что есть, и я должен с этим справиться.

Ответы [ 2 ]

2 голосов
/ 16 июля 2010

Если вы можете изменить схему, то лучший способ справиться с ней - использовать один столбец datetime2 вместо отдельных полей date и time. Ваш текущий запрос не сможет использовать индекс.

В противном случае вы можете попробовать переписать запрос следующим образом:

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 голосов
/ 16 июля 2010

В качестве альтернативы (так как крайнее ИЛИ - проклятие индексов)

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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...