c# - Getting the DateTime for the end of a certain day -
i have following
datetime today = datetime.today; // or datetime.utcnow.date; now, can not in linq-ef because date can not translated sql:
context.records.where(r => r.creationdate.date == today); so, this:
datetime dayend = today.adddays(1).addmilliseconds(-1); context.records.where(r => r.creationdate >= today && r.creationdate <= dayend); now, there better way getting end of time datetime instead of adding 1 day taking 1 millisecond?
the problem like
datetime today = datetime.today ; context.records.where(r => entityfunctions.truncatetime(r.creationdate) == today) ; is underlying sql going this:
select * some_table r convert(date,r.creationdate) == @today since column part of expression, sql engine unable make use of covering indices has available. unless you've got other criteria use indices, you're going table scan. , big tables, cause performance issue.
and should avoid obvious
datetime today = datetime.today ; datetime dayend = today.adddays(1).addmilliseconds(-1); context.records.where(r => r.creationdate >= today && r.creationdate <= dayend) ; because of way sql server datetime values work: while count in milliseconds, sql server's 'ticks' occur in 3- , 4-millisecond increments. details, see my answer question how sqldatetime precision reduction. in nutshell:
to conversion in manner in sql server it, following: take milliseconds portion of actual time under consideration, value 0-999, modulo 100. gives low order digit, value 0-9. if current time 23:57:23.559, milliseconds component 559. modulo 100 9.
- values 0 , 1 "rounded down" 0.
- values 2, 3 , 4 "rounded down"" 3.
- values 5, 6, 7 , 8 "rounded down" 7.
- a value of 9 rounded up 0. has rather unpleasant , nasty side effect: if milliseconds portion of time 999, ticks 1 millisecond. means time 23:59:59.999 rounded the next day. conversion of '31 dec 2010 23:59:59.999' yields datetime value of...1 january 2011 00:00:00.000.
note smalldatetime exhibits kind of behavior. datetime2 exempt.
so...
unless you're careful, it's easy drop things on floor have been timestamped right @ end-of-day (don't ask how know this).
you're better off doing like
datetime today = datetime.today ; datetime tomorrow = today.adddays(1); context.records.where(r => r.creationdate >= today && r.creationdate < tomorrow) ; which should translate sql looks like
select * some_table r r.creationdate >= @today , r.creationdate < @tomorrow and allow optimizer make use of indices on date/time column.
Comments
Post a Comment