J'ai besoin de traduire la requête LINQ suivante en Dynamic LINQ qui accepte plusieurs colonnes de regroupement en fonction de l'entrée de l'utilisateur. Fondamentalement, j'ai un tas de listes déroulantes qui appliquent des groupements et je ne veux pas énumérer toutes les combinaisons de groupements. Si Dynamic LINQ échoue, je peux avoir à construire une requête SQL manuellement, et personne ne veut cela.Dynamic LINQ GroupBy Colonnes multiples
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)
});
Je n'ai pas la moindre idée comment faire cela comme dynamique LINQ est totalement en situation irrégulière en dehors du « Bonjour tout le monde! » select/where/orderby cas. Je ne peux pas comprendre la syntaxe.
Quelque chose comme :(?)
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)");
J'utilise la classe DynamicQueryable dans System.Linq.Dynamic. Voir: http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
Suivi: La solution de Enigmativity a travaillé la plupart du temps. Pour une raison quelconque, il ne veut pas le groupe par la colonne datetime « StartOfWeek » - solution de contournement est juste pour faire un groupe secondaire:
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),
});
mais cela semble se dégrader sérieusement les performances ... =/
Merci beaucoup pour votre réponse complète. Je vais essayer ça demain et vous faire savoir si cela fonctionne pour moi - un coup d'œil rapide est encourageant. –
Cela ne semble pas grouper par StartOfWeek pour une raison quelconque.J'ai dû changer le code de regroupement pour chaque colonne à if (_section == "All") return _entry.Section; return _section; –
@ 'Daniel Coffman' - Je ne sais pas pourquoi il n'a pas été regroupé par' StartOfWeek', il aurait dû. J'ai revérifié le code et les méthodes 'Equals' &' GetHashCode' utilisent la valeur 'StartOfWeek'. Donnez-moi un cri si vous voulez que je l'examine plus avant. Je m'attendais à ce que le code de regroupement pour chaque colonne ait besoin d'être "modifié" un peu pour vos besoins. – Enigmativity