在运行时按日/周/月/年动态分组

我想基于传递给我的函数的int以不同的方式对查询进行分组。 目前我有这个非常hacky的解决方案:

`.GroupBy(occurrence => new { date = // Bucket by day. timeBucket == 0 ? DbFunctions.TruncateTime(occurrence.occurrenceDate) : // Bucket by week. timeBucket == 1 ? DbFunctions.AddDays(DbFunctions.CreateDateTime(occurrence.occurrenceDate.Year, 1, 1, 0, 0, 0), 7*(occurrence.occurrenceDate.DayOfYear/7)) : // Bucket by month. timeBucket == 2 ? DbFunctions.TruncateTime(DbFunctions.CreateDateTime(occurrence.occurrenceDate.Year, occurrence.occurrenceDate.Month, 1, 1, 1, 1)) : // Bucket by year. DbFunctions.TruncateTime(DbFunctions.CreateDateTime(occurrence.occurrenceDate.Year, 1, 1, 1, 1, 1)), type = occurrence.type })` 

我如何计算日期的具体细节对我来说并不重要(但无论如何都可以自由提供帮助)。 我想避免必须为数据库中的每一行查看此case语句。 无论如何要避免这样做吗? 我尝试过各种各样的解决方案,比如使用表达式,但我无法返回我想要的对象,因为表达式树必须是无参数的…

如果有人有解决方案,将非常感谢。

谢谢!

定义一个石斑鱼类:

 class TimeGrouper { public int Year { get; set; } public int Month { get; set; } public int Week { get; set; } public int Day { get; set; } } 

还有一个返回表达式的函数:

 using System.Data.Entity.SqlServer; ... Expression> GetGrouper(int grouping) { switch (grouping) { case 1: return o => new TimeGrouper { Year = o.occurrenceDate.Year }; case 2: return o => new TimeGrouper { Year = o.occurrenceDate.Year, Month = o.occurrenceDate.Month }; case 3: return o => new TimeGrouper { Year = o.occurrenceDate.Year, Week = SqlFunctions.DatePart("wk", o.StartDate).Value }; default: return o => new TimeGrouper { Year = o.occurrenceDate.Year, Day = SqlFunctions.DatePart("dy", o.StartDate).Value }; } } 

现在你可以打电话了

 db.Occurrences.GroupBy(GetGrouper(3)); 

为什么不做这样的事情(主要是伪代码):

 switch(timeBucket) { case 0: result=query.GroupBy(...); case 1: result=query.GroupBy(...); case 2: result=query.GroupBy(...); } 

按日期,月份,年份分组很容易。 周因您的日历周而异。

  List occurance = new List(); var dayGroup = occurance.GroupBy(x => x.Date); var yearGroup = occurance.GroupBy(x => x.Year); var monthGroup = occurance.GroupBy(x => newKeyValuePair(x.Month, x.Year));​