2010-03-24 37 views
0

我有一個無類型的數據表,看起來像這樣(srcTbl):如何使用LINQ在分組日期DataTable中轉換DataTable?

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,如果然後如何?

回答

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(); 

+0

它看起來如果在您的查詢中修復了列的計數,但我需要一個可以處理列數變量的查詢。 – 2010-03-24 12:05:53

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; 
    }