按范围内的所有日期分组
Group by ALL days in a range
我需要从一个范围内的每一天的查询中返回结果,即使数据库没有结果。
是否有一些我可以为此做的 groupBy 技巧,或者我是否必须将我的结果合并到一个预先生成的空结果列表中?
编辑:
到目前为止,我只有一个查询来获取每天的汇总结果(有结果)(略微修改以删除公司数据,所以我希望它仍然有意义!)
public List<MetricsResult> GetReport(DateTime toDate, DateTime fromDate)
{
var results =
context.Histories.Where(
history => (DbFunctions.TruncateTime(history.Sent) <= DbFunctions.TruncateTime(fromDate) &&
DbFunctions.TruncateTime(history.Sent) >= DbFunctions.TruncateTime(toDate)))
.GroupBy(h => DbFunctions.TruncateTime(h.Sent))
.Select(histories => new MetricsResult
{
Sent = histories.Count(f => f.Sent != null),
Unsubscribed = histories.Count(f => f.Unsubscribed.HasValue),
Day = histories.Key
});
return results.ToList();
}
如果您执行如下操作,使用 linq to objects
var days = Enumerable.Range(0, (toDate - fromDate).TotalDays)
.Select(i => fromDate.Date.AddDays(i));
您将获得范围内的每一天。
然后,如果您得到结果,而不是这样做,
var lookup = results.ToDictionary(mr => mr.Day, mr);
那你就可以了,
var newResults = days.Select(day =>
{
if (lookup.ContainsKey(day))
{
return lookup[day];
}
else
{
return new MetricsResult
{
Day = day
};
}
}).ToList();
并避免再次访问您的数据库。
如果您需要结果是 IQueryable
那是一个不同的命题,但是因为我在您的代码中看到 ToList()
这是一个更好的选择。
我需要从一个范围内的每一天的查询中返回结果,即使数据库没有结果。
是否有一些我可以为此做的 groupBy 技巧,或者我是否必须将我的结果合并到一个预先生成的空结果列表中?
编辑: 到目前为止,我只有一个查询来获取每天的汇总结果(有结果)(略微修改以删除公司数据,所以我希望它仍然有意义!)
public List<MetricsResult> GetReport(DateTime toDate, DateTime fromDate)
{
var results =
context.Histories.Where(
history => (DbFunctions.TruncateTime(history.Sent) <= DbFunctions.TruncateTime(fromDate) &&
DbFunctions.TruncateTime(history.Sent) >= DbFunctions.TruncateTime(toDate)))
.GroupBy(h => DbFunctions.TruncateTime(h.Sent))
.Select(histories => new MetricsResult
{
Sent = histories.Count(f => f.Sent != null),
Unsubscribed = histories.Count(f => f.Unsubscribed.HasValue),
Day = histories.Key
});
return results.ToList();
}
如果您执行如下操作,使用 linq to objects
var days = Enumerable.Range(0, (toDate - fromDate).TotalDays)
.Select(i => fromDate.Date.AddDays(i));
您将获得范围内的每一天。
然后,如果您得到结果,而不是这样做,
var lookup = results.ToDictionary(mr => mr.Day, mr);
那你就可以了,
var newResults = days.Select(day =>
{
if (lookup.ContainsKey(day))
{
return lookup[day];
}
else
{
return new MetricsResult
{
Day = day
};
}
}).ToList();
并避免再次访问您的数据库。
如果您需要结果是 IQueryable
那是一个不同的命题,但是因为我在您的代码中看到 ToList()
这是一个更好的选择。