#c# #.net #vb.net #linq #datatable
#c# #.net #vb.net #linq #datatable
Вопрос:
У меня есть datatable, подобный этому:
name | color of name
----------------------
x | red
y | blue
z | yellow
x | yellow
y | red
Мне нужно получить сводную таблицу этой таблицы следующим образом:
name | red | blue | yellow | total
-------------------------------------------------------
x | 1 | 0 | 1 | 2
y | 1 | 1 | 0 | 2
z | 0 | 0 | 1 | 1
Как я могу сделать это с помощью Linq в VB.NET ?
Цвета не являются динамическими. я могу поместить их в запрос в жестко закодированном виде.
Итак, мне нужно сгруппировать все записи по имени и сумме цветов записей в столбцах. Затем сумма общих цветов (если вы поможете в первом, я могу рассчитать итоговые значения: p)
Комментарии:
1. Я бы предложил рассматривать это как два шага: 1. сведите данные 2. Добавьте
total
столбец. Являются ли столбцыname
иcolor of name
ограниченными наборами данных или вам нужно полностью общее решение?2. Это поможет, если вы сможете отредактировать вопрос и объяснить, что вы уже пробовали.
3. @NetMage вы абсолютно правы. большая проблема в первую очередь. Названия цветов ограничены, они могут быть жестко запрограммированы. Мне нужно сгруппировать все записи по имени, имена чрезвычайно большого масштаба.
Ответ №1:
Я создал вариант моего DataTable
метода расширения pivot, который создает значение пересечения на основе наличия столбцов и добавляет столбец total.
public static class DataTableExt {
public static DataTable PivotByOverWithTotal(this DataTable dt, string ByRowFieldName, string OverColFieldName) {
var res = new DataTable();
if (dt.Rows.Count > 0) {
var dtg = dt.AsEnumerable().GroupBy(r => r[ByRowFieldName], r => r[OverColFieldName].ToString());
res.Columns.Add(ByRowFieldName, dt.Columns[ByRowFieldName].DataType);
var colNames = dtg.SelectMany(rg => rg).Distinct().OrderBy(n => n);
foreach (var n in colNames)
res.Columns.Add(n, typeof(int));
res.Columns.Add("Total", typeof(int));
foreach (var rg in dtg) {
var newr = res.NewRow();
newr[ByRowFieldName] = rg.Key;
int total = 0;
foreach (var rv in colNames) {
var val = rg.Contains(rv) ? 1 : 0;
newr[rv] = val;
total = val;
}
newr["Total"] = total;
res.Rows.Add(newr);
}
}
return res;
}
}
Вы используете это следующим образом:
var ansdt = src.PivotByOverWithTotal("name", "color");