Как я могу получить сводную таблицу из datable с использованием Linq в VB.NET ?

#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");