C#DataTable内部联接与动态列

我试图以与此问题类似的方式将两个DataTable连接在一起:

C#中DataTables的内部联接

我正在尝试将输出变为单个“组合”表,其中包含两个原始表中的列。 它们都有一个共同的日期戳列。

给出的答案适用于具有固定列的DataTables,但如果它们是动态创建的,并且可以包含任意数量的列,那么我该如何加入它们呢?

例如

T1 (datestamp, t1Column1, t1Column2, t1ColumnN...) T2 (datestamp, t2Column1, t2Column2, t2ColumnN...) 

我想加入以创建以下内容:

 J1 (datestamp, t1Column1, t1Column2, t1ColumnN, ..., t2Column1, t2Column2, t2ColumnN...) 

这可能吗?

我发现了一种不依赖于循环遍历列的解决方案。

它使用了’Merge’方法,我之前认为这是因为我认为两个表都需要相同的结构。

首先,您需要在两个数据表上创建主键:

 // set primary key T1.PrimaryKey = new DataColumn[] { T1.Columns["DateStamp"] }; T2.PrimaryKey = new DataColumn[] { T2.Columns["DateStamp"] }; 

然后将两个表添加到数据集中,以便添加关系:

 // add both data-tables to data-set DataSet dsContainer = new DataSet(); dsContainer.Tables.Add(T1); dsContainer.Tables.Add(T2); 

接下来添加数据集中两个键列之间的关系:

 // add a relationship between the two timestamp columns DataRelation relDateStamp = new DataRelation("Date", new DataColumn[] { T1.Columns["DateStamp"] }, new DataColumn[] { T2.Columns["DateStamp"] }); dsContainer.Relations.Add(relDateStamp); 

最后,您现在可以将第一个数据表复制到一个新的“组合”版本中,然后在第二个中合并:

 // populate combined data DataTable dtCombined = new DataTable(); dtCombined = T1.Copy(); dtCombined.Merge(T2, false, MissingSchemaAction.Add); 

注意:Merge方法要求第二个参数为false,否则它会复制结构但不复制第二个表的数据。

然后,这将结合以下表格:

 T1 (2012-05-09, 111, 222) T2 (2012-05-09, 333, 444, 555) 

到基于主键的组合版本:

 J1 (2012-05-09, 111, 222, 333, 444, 555) 

我认为您可以调整链接问题中的答案以使用列的索引 ,而不是列名称。 或者你可以循环遍历每一行中的项目,如下所示:

 foreach(DataRow row in table.Rows) { foreach(DataColumn column in table.Columns) { object value = row[column]; // add this to your combined table } } 

在厌倦了看到所有这些不能可靠地模拟SQL的内连接函数之后,我决定在这里自己创建:

 private DataTable JoinDataTables(DataTable t1, DataTable t2, params Func[] joinOn) { DataTable result = new DataTable(); foreach (DataColumn col in t1.Columns) { if (result.Columns[col.ColumnName] == null) result.Columns.Add(col.ColumnName, col.DataType); } foreach (DataColumn col in t2.Columns) { if (result.Columns[col.ColumnName] == null) result.Columns.Add(col.ColumnName, col.DataType); } foreach (DataRow row1 in t1.Rows) { var joinRows = t2.AsEnumerable().Where(row2 => { foreach (var parameter in joinOn) { if (!parameter(row1, row2)) return false; } return true; }); foreach (DataRow fromRow in joinRows) { DataRow insertRow = result.NewRow(); foreach (DataColumn col1 in t1.Columns) { insertRow[col1.ColumnName] = row1[col1.ColumnName]; } foreach (DataColumn col2 in t2.Columns) { insertRow[col2.ColumnName] = fromRow[col2.ColumnName]; } result.Rows.Add(insertRow); } } return result; } 

您可以如何使用此示例:

 var test = JoinDataTables(transactionInfo, transactionItems, (row1, row2) => row1.Field("TransactionID") == row2.Field("TransactionID"));