2015-06-26 6 views
1

Я хотел бы сгруппировать свой запрос по-разному на основе int, переданного в мою функцию. В настоящее время у меня есть это очень Hacky решение:Динамическая группировка по дням/неделям/месяцам/годам в Runtime

`.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 для каждой строки в базе данных. Есть ли вообще избежать этого? Я пробовал различные решения, такие как использование выражения, но я не мог вернуть объект, который мне нужен, потому что дерево выражений должно быть без параметров ...

Если у кого-то есть решение, было бы очень признательно.

Спасибо!

ответ

0

Определение класса Группировщик

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<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)); 
+0

Это сработало! Благодаря тонну! –

0

Почему бы просто не сделать что-то вроде этого (в основном псевдокоде):

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

Я использую синтаксис метода, а не синтаксис запроса ... Я не смог найти способ использования операторов switch в Linq с синтаксисом метода ...:/ –

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));​

Смежные вопросы