Necesito traducir la siguiente consulta LINQ a Dynamic LINQ que acepta varias columnas de agrupamiento según la entrada del usuario. Básicamente tengo un montón de listas desplegables que aplican agrupaciones y no quiero enumerar todas las combinaciones de agrupaciones. Si Dynamic LINQ falla, puedo tener que construir una consulta SQL manualmente, y nadie quiere eso.Dynamic LINQ GroupBy Columnas múltiples
var grouping = (from entry in ObjectContext.OmniturePageModules
where entry.StartOfWeek >= startDate && entry.StartOfWeek <= endDate &&
(section == "Total" || section == "All" || entry.Section == section) &&
(page == "Total" || page == "All" || entry.Page == page) &&
(module == "Total" || module == "All" || entry.Module == module)
group entry by new
{
entry.Page, // I want to be able to tell this anonymous type
entry.Module, // which columns to group by
entry.StartOfWeek // at runtime
}
into entryGroup
select new
{
SeriesName = section + ":" + entryGroup.Key.Page + ":" + entryGroup.Key.Module,
Week = entryGroup.Key.StartOfWeek,
Clicks = entryGroup.Sum(p => p.Clicks)
});
no tengo idea de cómo hacer esto tan dinámico LINQ está totalmente indocumentado fuera de la "Hello World!" select/where/orderby casos. Simplemente no puedo entender la sintaxis.
Algo así como :(?)
var grouping = ObjectContext.OmniturePageModules.Where(entry => entry.StartOfWeek >= startDate && entry.StartOfWeek <= endDate &&
(section == "Total" || section == "All" || entry.Section == section) &&
(page == "Total" || page == "All" || entry.Page == page) &&
(module == "Total" || module == "All" || entry.Module == module))
.GroupBy("new (StartOfWeek,Page,Module)", "it")
.Select("new (Sum(Clicks) as Clicks, SeriesName = section + key.Page + Key.Module, Week = it.Key.StartOfWeek)");
estoy usando la clase DynamicQueryable en System.Linq.Dynamic. Ver: http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
Seguimiento: solución de Enigmativity trabajó sobre todo . Por alguna razón, no quiere por el grupo de fecha y hora "StartOfWeek" columna - solución es sólo para hacer una agrupación secundaria:
var entries = (from entry in ObjectContext.OmniturePageModules
where entry.StartOfWeek >= startDate
&& entry.StartOfWeek <= endDate
&& (section == "Total" || section == "All" || entry.Section == section)
&& (page == "Total" || page == "All" || entry.Page == page)
&& (module == "Total" || module == "All" || entry.Module == module)
select entry).ToArray(); // Force query execution
var grouping = from entry in entries
let grouper = new EntryGrouper(entry, section, page, module)
group entry by grouper into entryGroup
select new
{
entryGroup.Key.SeriesName,
entryGroup.Key.Date,
Clicks = entryGroup.Sum(p => p.Clicks),
};
var grouping2 = (from groups in grouping
group groups by new {groups.SeriesName, groups.Date } into entryGroup
select new
{
entryGroup.Key.SeriesName,
entryGroup.Key.Date,
Clicks = entryGroup.Sum(p => p.Clicks),
});
pero esto parece degradar seriamente el rendimiento ... =/
Muchas gracias por su amplia respuesta. Trataré de hacerlo mañana y te dejaré saber si funciona para mí; un vistazo rápido es alentador. –
Esto no parece agruparse por StartOfWeek por alguna razón.Tuve que cambiar el código de agrupación para cada columna a if (_section == "All") return _entry.Section; return _section; –
@ 'Daniel Coffman' - No sé por qué no se ha agrupado por' StartOfWeek', debería haberlo hecho. Volví a verificar el código y los métodos 'Equals' y' GetHashCode' utilizan el valor 'StartOfWeek'. Dame un grito si quieres que lo investigue más. Esperaba que el código de agrupación para cada columna probablemente debería ser "ajustado" un poco para sus necesidades. – Enigmativity