2011-08-01 33 views
2

我有一個DataTable [有5列]來自數據庫的數據。 我需要通過此組合表調用一個組,並創建2個表...其中一個使用groupedBy行和其他具有項目。 什麼是最快的方式來做到這一點在C#代碼? 另外,我已經編寫了下面的代碼來爲這兩個表添加列。是否正確?創建數據表

繼承人我的代碼:

string colName = "ACCOUNT_ID"; 
var allRows = combinedTable.AsEnumerable();  

var accountRowGroups = allRows.GroupBy(row => row[colName]); 

DataTable masterDataTable = new DataTable(); 
DataTable childPricesDataTable = new DataTable(); 

// Create the columns 
      DataColumnCollection pdCols = combinedTable.Columns; 
      for (int ndx = 0; ndx < pdCols.Count; ndx++) 
      { 
       string columnName = pdCols[ndx].ColumnName; 
       Type type = Type.GetType(pdCols[ndx].DataType.ToString()); 

       masterDataTable.Columns.Add(columnName, type); 
       childPricesDataTable.Columns.Add(columnName, type); 

      } 

回答

4

看到類似的問題在這裏:How to merge multiple DataTable objects with group by with C# and concatinating duplicate rows?

我duffymo同意,這樣做在SQL,而不是在內存中的數據。

然而,如果這不是一個選項:

您可以添加兩個數據表之間的關係:http://codecorner.galanter.net/2009/04/20/group-by-and-aggregates-in-net-datatable/

這裏是:http://msdn.microsoft.com/en-us/library/ay82azad(v=vs.71).aspx

然後你就可以在合併數據表通過的潤集團從SQL團隊正確例如: http://weblogs.sqlteam.com/davidm/archive/2004/05/20/1351.aspx

public static DataTable GROUPBY(DataTable Table, DataColumn[] Grouping, string[] AggregateExpressions, string[] ExpressionNames, Type[] Types) 
     { 

      if (Table.Rows.Count == 0) 

       return Table; 

      DataTable table = SQLOps.PROJECT(Table, Grouping); 

      table.TableName = "GROUPBY"; 



      for (int i = 0; i < ExpressionNames.Length; i++) 
      { 

       table.Columns.Add(ExpressionNames[i], Types[i]); 

      } 



      foreach (DataRow row in table.Rows) 
      { 

       string filter = string.Empty; 



       for (int i = 0; i < Grouping.Length; i++) 
       { 

        //Determine Data Type   

        string columnname = Grouping[i].ColumnName; 

        object o = row[columnname]; 

        if (o is string || DBNull.Value == o) 
        { 

         filter += columnname + "='" + o.ToString() + "' AND "; 

        } 

        else if (o is DateTime) 
        { 

         filter += columnname + "=#" + ((DateTime)o).ToLongDateString() 

           + " " + ((DateTime)o).ToLongTimeString() + "# AND "; 

        } 

        else 

         filter += columnname + "=" + o.ToString() + " AND "; 

       } 

       filter = filter.Substring(0, filter.Length - 5); 



       for (int i = 0; i < AggregateExpressions.Length; i++) 
       { 

        object computed = Table.Compute(AggregateExpressions[i], filter); 

        row[ExpressionNames[i]] = computed; 

       } 

      } 

      return table; 

     } 
+0

感謝jeremy輸入。我想提一下,我已經使用DataRelation對象來綁定2個表[即。 masterDataTable和childPricesDataTable]到一個infragistics網格,但整個事情是非常緩慢的。因此,我正在尋找一種更快的方式在C#中。另外,當你說我可以用sql來代替時,你的意思是我從我的sql返回2個表比1組合表,然後使用DataRelation對象在網格中顯示它們? – Jimmy

+0

此外,@ duffymo談到在sql中結合2個表並返回需要的東西...如果我需要使用sql,那麼正如你在我上面的評論中可以看到的那樣,我將不得不發送2個表[master&child] 1,然後使用DataRelation對象在網格中顯示它們...你還會建議我使用sql嗎? – Jimmy

+0

您好@Jimmy,因爲你必須綁定兩個網格「一個用groupedBy行和其他有項目」 - 我會創建一個存儲過程並返回兩個SELECT,一個分組依據和另一個沒有分組。然後,我將使用此處描述的「使用NextResult檢索多個結果集」的DataReader.NextResult()方法http://msdn.microsoft.com/en-us/library/haa3afyz.aspx將這兩個網格僅綁定一次數據庫。當在SQL中執行JOIN操作時,尤其是當數據庫增長時,整個事情會更快。 HTH –

2

這不直接回答你的問題,但也許可以選擇(我相信更好)的方式來解決你的問題。

如果我理解正確,你有DataTable,一些定義的操作/過濾器,並希望返回模擬的DataTable作爲結果。但實際上DataTable的結果並不知道形狀(根據過濾器中的列可能會有所不同)。

考慮使用linq而不是操縱DataTables和DataRelations。 Linq支持你所提到的所有操作:分組,過濾,修整等等。

因此,您可能會返回可綁定的對象,因此您可以在網格中使用它,但方法定義會更清晰。