如何在C#中“联合”2个或更多DataTable?

如何在C#中“联合”2个或更多DataTable?

两个表都具有相同的结构。

是否有任何内置function或我们应该手动执行?

您最有可能使用DataTable.Merge方法。

示例

private static void DemonstrateMergeTable() { DataTable table1 = new DataTable("Items"); // Add columns DataColumn idColumn = new DataColumn("id", typeof(System.Int32)); DataColumn itemColumn = new DataColumn("item", typeof(System.Int32)); table1.Columns.Add(idColumn); table1.Columns.Add(itemColumn); // Set the primary key column. table1.PrimaryKey = new DataColumn[] { idColumn }; // Add RowChanged event handler for the table. table1.RowChanged += new System.Data.DataRowChangeEventHandler(Row_Changed); // Add ten rows. DataRow row; for (int i = 0; i <= 9; i++) { row = table1.NewRow(); row["id"] = i; row["item"] = i; table1.Rows.Add(row); } // Accept changes. table1.AcceptChanges(); PrintValues(table1, "Original values"); // Create a second DataTable identical to the first. DataTable table2 = table1.Clone(); // Add column to the second column, so that the // schemas no longer match. table2.Columns.Add("newColumn", typeof(System.String)); // Add three rows. Note that the id column can't be the // same as existing rows in the original table. row = table2.NewRow(); row["id"] = 14; row["item"] = 774; row["newColumn"] = "new column 1"; table2.Rows.Add(row); row = table2.NewRow(); row["id"] = 12; row["item"] = 555; row["newColumn"] = "new column 2"; table2.Rows.Add(row); row = table2.NewRow(); row["id"] = 13; row["item"] = 665; row["newColumn"] = "new column 3"; table2.Rows.Add(row); // Merge table2 into the table1. Console.WriteLine("Merging"); table1.Merge(table2, false, MissingSchemaAction.Add); PrintValues(table1, "Merged With table1, schema added"); } private static void Row_Changed(object sender, DataRowChangeEventArgs e) { Console.WriteLine("Row changed {0}\t{1}", e.Action, e.Row.ItemArray[0]); } private static void PrintValues(DataTable table, string label) { // Display the values in the supplied DataTable: Console.WriteLine(label); foreach (DataRow row in table.Rows) { foreach (DataColumn col in table.Columns) { Console.Write("\t " + row[col].ToString()); } Console.WriteLine(); } } 

你可以试试这个:

 public static DataTable Union (DataTable First, DataTable Second) { //Result table DataTable table = new DataTable("Union"); //Build new columns DataColumn[] newcolumns = new DataColumn[First.Columns.Count]; for(int i=0; i < First.Columns.Count; i++) { newcolumns[i] = new DataColumn( First.Columns[i].ColumnName, First.Columns[i].DataType); } table.Columns.AddRange(newcolumns); table.BeginLoadData(); foreach(DataRow row in First.Rows) { table.LoadDataRow(row.ItemArray,true); } foreach(DataRow row in Second.Rows) { table.LoadDataRow(row.ItemArray,true); } table.EndLoadData(); return table; } 

从这里 (未经测试)。

您可以使用Linq中的Concat到数据集(获取LINQ in Action的免费章节)来加入它们,然后使用.AsDataTable来创建表(假设您确实希望它们作为DataTable)

偶然发现了这个问题,Ruben Bartelink给出了一个很好的答案,但没有代码。 所以我不得不在其他地方查找它,这违背了StackOverflow的要点。 现在是2010年,给出的其他答案并不那么可行。 作为参考,这里的代码演示了CopyToDataTable()扩展方法。 这是在VB中,如果他想重温过去并发布更完整的答案,就不要从Ruben那里窃取信用:)

 Public Function GetSchema(ByVal dbNames As IEnumerable(Of String)) As DataTable Dim schemaTables As New List(Of DataTable)() For Each dbName As String In dbNames Dim cnnStr = GetConnectionString(dbName) Dim cnn As New SqlConnection(cnnStr) cnn.Open() Dim dt = cnn.GetSchema("Columns") cnn.Close() schemaTables.Add(dt) Next Dim dtResult As DataTable = Nothing For Each dt As DataTable In schemaTables If dtResult Is Nothing Then dtResult = dt Else dt.AsEnumerable().CopyToDataTable(dtResult, LoadOption.PreserveChanges) End If Next Return dtResult End Function 

尝试使用Linq to DataSet,必须添加System.Data.DataSetExtensions.dll的引用,另一种方法,DataTable.Merge方法的替代方法)。

 static void Main(string[] args) { DoUnion(); } private static void DoUnion() { DataTable table1 = GetProducts(); DataTable table2 = NewProducts(); var tbUnion = table1.AsEnumerable() .Union(table2.AsEnumerable()); DataTable unionTable = table1.Clone(); foreach (DataRow fruit in tbUnion) { var fruitValue = fruit.Field(0); Console.WriteLine("{0}->{1}", fruit.Table, fruitValue); DataRow row = unionTable.NewRow(); row.SetField(0, fruitValue); unionTable.Rows.Add(row); } } private static DataTable NewProducts() { DataTable table = new DataTable("CitricusTable"); DataColumn col = new DataColumn("product", typeof(string)); table.Columns.Add(col); string[] citricusFruits = { "Orange", "Grapefruit", "Lemon", "Lime", "Tangerine" }; foreach (string fruit in citricusFruits) { DataRow row = table.NewRow(); row.SetField(col, fruit); table.Rows.Add(row); } return table; } private static DataTable GetProducts() { DataTable table = new DataTable("MultipleFruitsTable"); DataColumn col = new DataColumn("product", typeof(string)); table.Columns.Add(col); string[] multipleFruits = { "Breadfruit", "Custardfruit", "Jackfruit", "Osage-orange", "Pineapple" }; foreach (string fruit in multipleFruits) { DataRow row = table.NewRow(); row.SetField(col, fruit); table.Rows.Add(row); } return table; } 

安东尼奥