Agrupación dinámica por día / semana / mes / año en tiempo de ejecución

Me gustaría agrupar mi consulta de forma diferente según un int que se haya transferido a mi función. Actualmente tengo esta solución muy 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 })` 

Los detalles de cómo calculo las fechas no son muy importantes para mí (pero siéntase libre de dar ayuda de todos modos). Me gustaría evitar tener que pasar por esta statement de caso para cada fila en la base de datos. ¿Hay alguna forma de evitar hacer esto? He intentado una variedad de soluciones como usar una expresión, pero no pude devolver el objeto que quería porque el árbol de expresiones debe ser sin parámetros …

Si alguien tiene una solución sería muy apreciado.

¡Gracias!

Definir una clase de mero:

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

Y una función para devolver una expresión:

 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 }; } } 

Ahora puedes llamar

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

¿Por qué no hacer algo como esto (en su mayoría pseudo código):

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

Agrupar por fecha, mes, año es fácil. La semana varía dependiendo de su semana del calendario.

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