Мне нужно перевести следующий запрос LINQ в Dynamic LINQ, который принимает несколько столбцов группировки на основе ввода пользователем. В основном у меня есть группа dropdownlists, которые применяют группировки, и я не хочу перечислять каждую комбинацию групп. Если Dynamic LINQ терпит неудачу, мне, возможно, придется создать SQL-запрос вручную, и никто этого не хочет.Динамический LINQ GroupBy Несколько столбцов
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)
});
Я понятия не имею, как это сделать, как Dynamic LINQ полностью документирована вне «привет мир!» выберите/где/порядок. Я просто не могу понять синтаксис.
Что-то вроде :(?)
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)");
Я использую класс DynamicQueryable в System.Linq.Dynamic. См: http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
Последующая деятельность: решение Enigmativity работал основном. По какой-то причине не хочет группы по DateTime «StartOfWeek» колонка - обходной путь, это просто сделать вторичную группировку:
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),
});
, но это, кажется, серьезно ухудшить производительность ... =/
Большое спасибо за ваш обширный ответ. Я попробую это завтра и сообщит, будет ли это работать для меня - быстрый взгляд на него обнадеживает. –
По какой-то причине это не похоже на группу StartOfWeek.Мне пришлось изменить код группировки для каждого столбца, если (_section == "All") return _entry.Section; return _section; –
@ 'Даниэль Коффман' - Я не знаю, почему он не сгруппирован по« StartOfWeek », он должен иметь. Я перепроверил код, а методы 'Equals' &' GetHashCode' используют значение «StartOfWeek». Дайте мне крик, если вы хотите, чтобы я заглянул в нее дальше. Я ожидал, что код группировки для каждого столбца, вероятно, потребуется немного «настроить» для ваших нужд. – Enigmativity