使用按日,月,qtr,年等分组的实体框架汇总日期数据

时间:2014-08-08 13:00:58

标签: entity-framework

我有一张记录活动的表格。所有活动都有活动日期。我想计算给定时间段(日,月,qtr等)的活动数量。我想包括所有日期,即使是没有活动的日期。我可以在Data Tier中使用DateDimension表执行此操作,其中日期表有一个名为day的列,每个日历日包含一行,外部联接按查询分组:

DateDimension表
|日|
| 2013年1月1日00:00:00 |
| 2013年1月1日00:00:00 |
| 2013年1月1日00:00:00 |

查询

SELECT CAST(Day AS DATE), COUNT() AS CountOfActivities
FROM DateDimension dd LEFT OUTER JOIN Activities a  
    ON CAST(dd.Day AS DATE) = CAST(a.ActivityDate AS DATE)
WHERE Day BETWEEN MyStartDate AND MyEndDate
GROUP BY CAST(Day AS DATE)
ORDER BY CAST(Day AS DATE)

我正在使用EntityFramework,所以我想使用Linq执行此查询。 DateDimension表没有驻留在数据库中的业务值。它的存在只是为了通过提供日期列表来支持这些聚合查询,因此如果给定日期没有活动,我可以确保返回一行。

我认为我可以在内存中制作一个天数列表,并在运行时将它们编织成更简单的数据库查询的结果。通过连接来自2个IEnumerables的结果 - 1来自内存中的可触及日期和另一个来自数据库结果。我怎么能这样做?我应该这样做吗?

1 个答案:

答案 0 :(得分:1)

这样的事情怎么样:

日期范围示例:

var from = DateTime.Today.AddDays(-30);
var to = DateTime.Today;

每天举行活动记录的词典:

var activityCounts = new Dictionary<DateTime, int>();

种子在范围内每天计数为零(这相当于设置日期维度表):

Enumerable.Range(0, (to - from).Days + 1)
    .ToList()
    .ForEach(x => activityCounts[from.AddDays(x)] = 0); 

在范围内添加每天的实际活动计数:

context.Activities.Where(a => a.DateTime >= from && a.DateTime <= to)
    .GroupBy(a => a.DateTime)
    .ToList()
    .ForEach(x => activityCounts[x.Key] = x.Count()); 

通过这种方式,您只需访问数据库以进行活动日期的活动聚合。然后,在应用程序服务器上执行结果集的填充以及日期范围内的连续日期。

只需要注意日期是如何存储在数据库中的。此代码示例期望能够根据对DateTime.Today的调用格式匹配活动字典中的键。您需要相应地在数据库查询中设置日期。