我有以下代码:
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);
}
此代码运行良好,但问题是DateTime在数据库中存储为UTC。在我进行GroupBy操作的那一刻,我失去了Time部分。因此,如果我尝试使用以下内容将其转换回本地时间:
return result.ToDictionary(x => new DateTime(x.Date.Year, x.Date.Month, x.Date.Day).ToLocalTime().ToShortDateString(), x => x.Count);
这将基于不同的时间,因此不正确。该列必须保留DateTime。
有什么建议吗?
答案 0 :(得分:0)
听起来真正的挑战是你需要翻译两次。首先,采用当地的DateTime,您需要将该方法(您的问题只有在本地时才有意义)转换为UTC以进行查询。但是,在你对服务器进行分组之前,你需要将x.CreatedAt翻译成本地,换句话说。这很棘手,但如果您在System.Data.Objects.SqlClient中使用SqlFunctions库,则可以正常工作。这就是它的样子。凌乱,我不知道它有多高效,但它应该有用。
public IDictionary<string, int> GetCountByDate(DateTime fromDate, DateTime toDate)
{
DateTime utcFrom = fromDate.ToUniversalTime();
DateTime utcTo = toDate.ToUniversalTime();
int offset = (int)(fromDate - utcFrom).TotalHours;
var result = Database.Set<User>().Where(x => x.CreatedAt >= utcFrom && x.CreatedAt <= utcTo)
.GroupBy(x => new {
SqlFunctions.DateAdd("hh", offset, x.CreatedAt).Value.Year,
SqlFunctions.DateAdd("hh", offset, x.CreatedAt).Value.Month,
SqlFunctions.DateAdd("hh", offset, x.CreatedAt).Value.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);
}
此时,字典对象中的日期值已经是本地时间,因此无需将它们转换为演示文稿。