views:

35

answers:

2

I have the following query:

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

This generates some horendous looking SQL, looking something like this:

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

What is the reason for this massive amount of SQL? And is there a better way to deal with it?

EDIT:

I have no control over the schema. It is what it is, and I have to deal with it.

+2  A: 

If you can change the schema then the best way to deal with it is to use a single datetime2 column instead of separate date and time fields. Your current query will not be able to use an index.

Otherwise you could try rewriting the query as follows:

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; 

The SQL generated by this query might be slightly more readable and perhaps also more efficient. On the other hand, from a programmer's perspective it is more important that the source code is readable than the generated SQL is readable. If performance is not a concern you may want to leave your code as it is and just accept that the generated SQL is ugly and not worry about it.

Mark Byers
I would love to, but cannot. It would break the existing application which we have no source for.
Mystere Man
@Mystere Man: Have you considered adding the datetime2 as a computed column? If you persist it you can even index it. Adding an extra column without changing any existing columns has a reasonably good chance of not breaking the existing application (although you will need to test it thoroughly to be sure). http://msdn.microsoft.com/en-us/library/ms191250.aspx
Mark Byers
My assumption was that due to all the calculations in the generated SQL, it would be significantly slower. No, I did not measure this, and Knuth quotes aside, I prefer cleaner sql when possible.
Mystere Man
It seems like the TimeOfDay stuff is where the extra SQL comes in, it has to break it out into seconds or something.
Mystere Man
A: 

As an alternative (since outermost OR is the bane of indexes)

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;
David B