如何使用LINQ在分组日期DataTable中转换DataTable?

时间:2010-03-24 09:50:46

标签: .net linq datatable

我有一个看起来像这样的无类型DataTable(srcTbl):

date            col_1   col_2 ...  col_n
1.3.2010 00:00  12.5    0     ...  100 
1.3.2010 01:00  0       0     ...  100 
1.3.2010 22:00  0       0     ...  100 
1.3.2010 23:00  12.5    0     ...  100 
...
31.3.2010 00:00 2       0     ...  100
31.3.2010 01:00 2       0     ...  200

我需要总结按日期分组的行以获得类似的数据表(dstTbl):

date,           col_1   col_2 ...  col_n
1.3.2010        15      0     ...  400
...
31.3.2010       4       0     ...  300

这是否可以通过使用LINQ,如果可以的话?

2 个答案:

答案 0 :(得分:1)

好的,所以你可以像这样实现它。这是一个工作版本,所以你不应该有太多问题。

 

DataTable myDataTable = new DataTable(); myDataTable.Columns.Add("Date", typeof(DateTime)); myDataTable.Columns.Add("Col1", typeof(int)); myDataTable.Columns.Add("Col2", typeof(int)); myDataTable.Columns.Add("Col3", typeof(int));

        var datarow1 = myDataTable.NewRow();
        datarow1.SetField("Date", DateTime.Parse("01/03/09 00:01:00"));
        datarow1.SetField("Col1", 12);
        datarow1.SetField("Col2", 0);
        datarow1.SetField("Col3", 100);

        var datarow2 = myDataTable.NewRow();
        datarow2.SetField("Date", DateTime.Parse("01/03/09 01:03:00"));
        datarow2.SetField("Col1", 12);
        datarow2.SetField("Col2", 0);
        datarow2.SetField("Col3", 100);

        var datarow3 = myDataTable.NewRow();
        datarow3.SetField("Date", DateTime.Parse("01/03/09 02:05:00"));
        datarow3.SetField("Col1", 0);
        datarow3.SetField("Col2", 0);
        datarow3.SetField("Col3", 100);

        var datarow4 = myDataTable.NewRow();
        datarow4.SetField("Date", DateTime.Parse("10/10/09 00:03:00"));
        datarow4.SetField("Col1", 2);
        datarow4.SetField("Col2", 0);
        datarow4.SetField("Col3", 100);

        var datarow5 = myDataTable.NewRow();
        datarow5.SetField("Date", DateTime.Parse("31/03/09 01:03:00"));
        datarow5.SetField("Col1", 2);
        datarow5.SetField("Col2", 0);
        datarow5.SetField("Col3", 100);

        var datarow6 = myDataTable.NewRow();
        datarow6.SetField("Date", DateTime.Parse("31/03/09 03:04:00"));
        datarow6.SetField("Col1", 2);
        datarow6.SetField("Col2", 0);
        datarow6.SetField("Col3", 100);

        myDataTable.Rows.Add(datarow1);
        myDataTable.Rows.Add(datarow2);
        myDataTable.Rows.Add(datarow3);
        myDataTable.Rows.Add(datarow4);
        myDataTable.Rows.Add(datarow5);
        myDataTable.Rows.Add(datarow6);

        var q = (from t in myDataTable.AsEnumerable()
                 group t by new {t.Field<DateTime>("Date").Day, t.Field<DateTime>("Date").Month, t.Field<DateTime>("Date").Year}
                 into temp
                    select myDataTable.LoadDataRow(
                    new object[]
                        {
                            string.Format("{0}.{1}.{2}", temp.Key.Day, temp.Key.Month, temp.Key.Year),
                            temp.Sum(r => r.Field<int>("Col1")),
                            temp.Sum(r => r.Field<int>("Col2")),
                            temp.Sum(r => r.Field<int>("Col3")),
                        }, LoadOption.PreserveChanges));

        DataTable newTable = q.CopyToDataTable();

var datarow1 = myDataTable.NewRow(); datarow1.SetField("Date", DateTime.Parse("01/03/09 00:01:00")); datarow1.SetField("Col1", 12); datarow1.SetField("Col2", 0); datarow1.SetField("Col3", 100); var datarow2 = myDataTable.NewRow(); datarow2.SetField("Date", DateTime.Parse("01/03/09 01:03:00")); datarow2.SetField("Col1", 12); datarow2.SetField("Col2", 0); datarow2.SetField("Col3", 100); var datarow3 = myDataTable.NewRow(); datarow3.SetField("Date", DateTime.Parse("01/03/09 02:05:00")); datarow3.SetField("Col1", 0); datarow3.SetField("Col2", 0); datarow3.SetField("Col3", 100); var datarow4 = myDataTable.NewRow(); datarow4.SetField("Date", DateTime.Parse("10/10/09 00:03:00")); datarow4.SetField("Col1", 2); datarow4.SetField("Col2", 0); datarow4.SetField("Col3", 100); var datarow5 = myDataTable.NewRow(); datarow5.SetField("Date", DateTime.Parse("31/03/09 01:03:00")); datarow5.SetField("Col1", 2); datarow5.SetField("Col2", 0); datarow5.SetField("Col3", 100); var datarow6 = myDataTable.NewRow(); datarow6.SetField("Date", DateTime.Parse("31/03/09 03:04:00")); datarow6.SetField("Col1", 2); datarow6.SetField("Col2", 0); datarow6.SetField("Col3", 100); myDataTable.Rows.Add(datarow1); myDataTable.Rows.Add(datarow2); myDataTable.Rows.Add(datarow3); myDataTable.Rows.Add(datarow4); myDataTable.Rows.Add(datarow5); myDataTable.Rows.Add(datarow6); var q = (from t in myDataTable.AsEnumerable() group t by new {t.Field<DateTime>("Date").Day, t.Field<DateTime>("Date").Month, t.Field<DateTime>("Date").Year} into temp select myDataTable.LoadDataRow( new object[] { string.Format("{0}.{1}.{2}", temp.Key.Day, temp.Key.Month, temp.Key.Year), temp.Sum(r => r.Field<int>("Col1")), temp.Sum(r => r.Field<int>("Col2")), temp.Sum(r => r.Field<int>("Col3")), }, LoadOption.PreserveChanges)); DataTable newTable = q.CopyToDataTable();

答案 1 :(得分:0)

我找到了解决问题的方法,但是我必须在for循环中处理每个列。也许有人知道如何放过这个。

    public static DataTable HoursToDailySums(DataTable src_tbl)
    {
        DataTable dst_tbl = src_tbl.Clone();

        // handle the dates column
        var qry = from row in src_tbl.AsEnumerable()
                  group row by ((DateTime)row[0]).Date into g
                  orderby g.Key
                  select g.Key;

        foreach(DateTime date in qry)
        {
            DataRow new_row = dst_tbl.NewRow();
            new_row[0] = date;
            dst_tbl.Rows.Add(new_row);
        }

        // handle all other columns
        for (int col = 1; col < dst_tbl.Columns.Count; col++)
        {
            var sumQry = from row in src_tbl.AsEnumerable()
                         group row by ((DateTime)row[0]).Date into g
                         orderby g.Key
                         select g.Sum(row => row.Field<double>(col));

            int row_index = 0;
            foreach(double sum in sumQry)
            {
                dst_tbl.Rows[row_index++][col] = sum;
            }
        }
        return dst_tbl;
    }