Динамический Linq со словарными ключами - PullRequest
0 голосов
/ 25 июня 2018

В настоящее время у меня есть фрагмент кода, который принимает DataView, выбирает значения одного столбца, группирует по этим значениям, затем выводит счетчик (чтобы получить гистограмму, своего рода):

string columnName;
var dataSource = grid.DataSource as System.Data.DataView;
var values = dataSource.OfType<System.Data.DataRowView>()
                       .Select(r => r[columnName]);

_GroupedRowCounts = values.GroupBy(r => r[columnName])
                          .ToDictionary(v => v.Key, v => v.Count());

`` `

Это прекрасно работает, но оказывается, мне нужно сгруппировать по произвольному количеству столбцов, которые я не знаю во время компиляции.

Я предполагаю, что могу использоватьSystem.Linq.Dynamic для этого, но я обнаружил, что его документации довольно не хватает (начиная с: какой из проектов GitHub является текущим?).Очевидно, я могу использовать DynamicExpression.CreateClass() для динамического создания класса со свойствами, основанными на столбцах, по которым я хочу сгруппировать, что-то вроде:

List<DataColumn> columns;
Type dynamicDataClass = DynamicExpression.CreateClass(columns.Select(c => new DynamicProperty(c.ColumnName, c.DataType)));

Однако мне неясно:

  • как мне затем передать этот класс вызовам Select и GroupBy?System.Linq.Dynamic предоставляет перегрузку Select (), которая принимает строку - я просто передаю имена свойств класса?Как System.Linq.Dynamic узнает, как использовать динамически генерируемый тип?
  • как мне заполнить это значениями?Я знаю, что могу использовать Активатор, чтобы сделать это вручную, но есть ли встроенный способ сопоставления этого со значениями исходных объектов, или мне нужно сделать это на заказ?
  • Я даже направильный путь вообще?Кажется, что примеры не используют DynamicExpression и т. Д., А скорее просто строки.

1 Ответ

0 голосов
/ 25 июня 2018

Этот ответ предназначен для тех случаев, когда вы хотите обойти использование внешней библиотеки.Это будет немного более неэффективно, чем использование библиотеки.Кажется, что есть еще одна библиотека, которую вы можете попробовать, называется Linq.Dynamic.Core.Это кажется немного более надежным.

Я бы преобразовал результат вашего запроса linq в список типа Dictionary.Использование верхнего ответа из этого поста: LINQ-запрос для возврата в словарь

Затем вы можете сортировать, делая что-то вроде этого:

List<Dictionary<string, string>> list = new List<Dictionary<string, string>>();

list.OrderBy(x => x["columnName"]).ToList();
...