[英]C# DataTable Inner join with dynamic columns
我試圖以與此問題類似的方式將兩個DataTable連接在一起:
我正在嘗試將輸出變為單個“組合”表,其中包含兩個原始表中的列。 它們都有一個共同的日期戳列。
給出的答案適用於具有固定列的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)
在厭倦了看到所有這些不能可靠地模擬SQL的內連接函數之后,我決定在這里創建自己的函數:
private DataTable JoinDataTables(DataTable t1, DataTable t2, params Func<DataRow, DataRow, bool>[] 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<int>("TransactionID") == row2.Field<int>("TransactionID"));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.