I have the following code:
public IDictionary<string, int> GetCountByDate(DateTime fromDate, DateTime toDate)
{
var result = Database.Set<User>().Where(x => x.CreatedAt >= fromDate && x.CreatedAt <= toDate).GroupBy(x => new { x.CreatedAt.Year, x.CreatedAt.Month, x.CreatedAt.Day }).Select(x => new { Date = x.Key, Count = x.Count() });
return result.ToDictionary(x => new DateTime(x.Date.Year, x.Date.Month, x.Date.Day).ToShortDateString(), x => x.Count);
}
This code works perfectly well but the problem is that the DateTime is stored as UTC in the database. The moment I do the GroupBy operation I lose the Time part. So if I tried to convert it back to loca time with the following:
return result.ToDictionary(x => new DateTime(x.Date.Year, x.Date.Month, x.Date.Day).ToLocalTime().ToShortDateString(), x => x.Count);
It would be based on a different time and therefore incorrect. The column has to stay DateTime.
Any suggestions?
It sounds like the real challenge is that you’ll need to translate twice. First, taking the local DateTime you’re feeding into the method (your question only makes sense if those are local) need to be translated into UTC for the query. But then you need to translate x.CreatedAt into local before you do your grouping—on the server, in other words. This is tricky, but works if you use the SqlFunctions library in System.Data.Objects.SqlClient. Here’s what it’d look like. Messy and I don’t know how performant it’d be, but it should work.
At that point, the date values in your dictionary object are already in local time, so no need to convert them for presentation.