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

时间:2015-06-26 22:00:03

标签: c# linq linq-to-entities

我希望根据传入我的函数的int对查询进行不同的分组。目前我有这个非常讨厌的解决方案:

`.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语句。无论如何要避免这样做吗?我尝试了各种各样的解决方案,比如使用表达式,但我无法返回我想要的对象,因为表达式树必须是无参数的...

如果有人有解决方案,我们将不胜感激。

谢谢!

3 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

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



            List<DateTime> occurance = new List<DateTime>();

            var dayGroup = occurance.GroupBy(x => x.Date);
            var yearGroup = occurance.GroupBy(x => x.Year);
            var monthGroup = occurance.GroupBy(x => newKeyValuePair<int,int>(x.Month, x.Year));​
&#13;
&#13;
&#13;

答案 2 :(得分:0)

定义一个石斑鱼类:

using System.Data.Entity.SqlServer;
...
Expression<Func<Occurrence, TimeGrouper>> 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));

现在你可以打电话了

value