你可以在這裏使用這個擴展方法,我最近從零開始編寫了another question。它可以通過一個公共密鑰合併多個表。如果沒有密鑰被指定它將只使用默認DataTable.Merge
方法:
public static DataTable MergeAll(this IList<DataTable> tables, String primaryKeyColumn)
{
if (!tables.Any())
throw new ArgumentException("Tables must not be empty", "tables");
if(primaryKeyColumn != null)
foreach(DataTable t in tables)
if(!t.Columns.Contains(primaryKeyColumn))
throw new ArgumentException("All tables must have the specified primarykey column " + primaryKeyColumn, "primaryKeyColumn");
if(tables.Count == 1)
return tables[0];
DataTable table = new DataTable("TblUnion");
table.BeginLoadData(); // Turns off notifications, index maintenance, and constraints while loading data
foreach (DataTable t in tables)
{
table.Merge(t); // same as table.Merge(t, false, MissingSchemaAction.Add);
}
table.EndLoadData();
if (primaryKeyColumn != null)
{
// since we might have no real primary keys defined, the rows now might have repeating fields
// so now we're going to "join" these rows ...
var pkGroups = table.AsEnumerable()
.GroupBy(r => r[primaryKeyColumn]);
var dupGroups = pkGroups.Where(g => g.Count() > 1);
foreach (var grpDup in dupGroups)
{
// use first row and modify it
DataRow firstRow = grpDup.First();
foreach (DataColumn c in table.Columns)
{
if (firstRow.IsNull(c))
{
DataRow firstNotNullRow = grpDup.Skip(1).FirstOrDefault(r => !r.IsNull(c));
if (firstNotNullRow != null)
firstRow[c] = firstNotNullRow[c];
}
}
// remove all but first row
var rowsToRemove = grpDup.Skip(1);
foreach(DataRow rowToRemove in rowsToRemove)
table.Rows.Remove(rowToRemove);
}
}
return table;
}
你可以把它用這種方式:
var tables= new[] { Schema1, Schema2};
DataTable Schema3 = tables.MergeAll("ID");
編輯:如果你不需要一個新的DataTable
與你也可以使用Linq-To-DataSet
(現VB.NET)合併模式:
Dim schema3 = From r1 In schema1
Join r2 In schema2 On r1.Field(Of Int32)("ID") Equals r2.Field(Of Int32)("ID")
Select New With {
.ID = r1.Field(Of Int32)("ID"),
.Food = r1.Field(Of String)("Food"),
.Book = r1.Field(Of String)("Book"),
.Rice = r1.Field(Of String)("Rice"),
.Cave = r1.Field(Of String)("Cave"),
.Carpet = r2.Field(Of String)("Carpet"),
.Strings = r2.Field(Of String)("Strings"),
.Run = r2.Field(Of String)("Run")
}
你需要一個新的合併DataTable嗎?或者一個匿名類型是否足夠? –
只要我可以在表格的內容提供給報表查看器的過程結束時,我不會發現這兩種方式都無關緊要。 – Ccorock
數據庫也會這樣做,你可以使用UNION關鍵字。 –