web-dev-qa-db-ja.com

Linqを使用したGroupByおよびSumデータテーブル

こんにちは、私はこのようなデータテーブルを持っています:

 Id金額1金額2金額3 
 1 2 2 2 
 12 4 6 4 
 12 6 6 5 
 22 7 2 1 
 22 7 2 2 

このようにデータテーブルを取得する必要があります:

 Id金額1金額2金額3 
 1 2 2 2 
 12 10 12 9 
 22 14 4 3 

私はもともと無名メソッドでそれをやろうとしましたが、無名メソッドでは実行できない別のクラスに返す必要があります。私の2番目の試みは、これを実行して返せるようにすることでした。

DataTable ddt = dt.AsEnumerable()
        .Sum(g => g.Field<int>("Amount 1"))
        .GroupBy(g => new { Col1 = g["ID"] })
        .Select(g => g.OrderBy(r => r["ID"]).First())
        .CopyToDataTable();

このコードはコンパイルできませんが、可能であればヘルプやアドバイスをいただければ幸いです。私はlinqに非常に慣れていません。

6
Leon Winston

最初にGroupByを実行し、次にグループをDataRowsに投影してから、DataTable拡張を使用してCopyToDataTableを作成できます。

var newDt = dt.AsEnumerable()
              .GroupBy(r => r.Field<int>("Id"))
              .Select(g =>
              {
                  var row = dt.NewRow();

                  row["Id"] = g.Key;
                  row["Amount 1"] = g.Sum(r => r.Field<int>("Amount 1"));
                  row["Amount 2"] = g.Sum(r => r.Field<int>("Amount 2"));
                  row["Amount 3"] = g.Sum(r => r.Field<int>("Amount 3"));

                  return row;
              }).CopyToDataTable();
21
Arturo Menchaca

これでうまくいきます。 10進値があり、データテーブルを変数ではなくデータテーブルとして使用する場合に、キャストの問題に役立つようにArturoのコードを少し変更しました。 (r [15]は合計する列です)

                  dt = dt.AsEnumerable()
                    .GroupBy(r => r["fldReportCode"])
                    .Select(g =>
                     {
                        var row = dt.NewRow();

                      row["fldReportCode"] = g.Key;
                      row[15] = g.Sum(r => (decimal)r[15]);
                      //row["Amount 2"] = g.Sum(r => r.Field<int>("Amount 2"));
                      //row["Amount 3"] = g.Sum(r => r.Field<int>("Amount 3"));

                          return row;
                      }).CopyToDataTable();
1

呼び出しが順不同です。以下のコードはデータをテーブルに入れませんが、簡単にテーブルに入れることができるデータを提供します。

dt.AsEnumberable()
    .GroupBy(g => g["ID])
    .Select(g => new {
        Id = g.Key, 
        Amount1 = g.Sum(s => s.Amount1), 
        Amount2 = g.Sum(s => s.Amount2), 
        Amount3 = g.Sum(s => s.Amount3)});
1
pquest