【发布时间】:2013-07-16 18:38:19
【问题描述】:
如何在保留两个表中的所有列的同时将两个数据表与以下表和条件进行左外连接?
dtblLeft:
id col1 anotherColumn2
1 1 any2
2 1 any2
3 2 any2
4 3 any2
5 3 any2
6 3 any2
7 any2
dtblRight:
col1 col2 anotherColumn1
1 Hi any1
2 Bye any1
3 Later any1
4 Never any1
dtbl已加入:
id col1 col2 anotherColumn1 anotherColumn2
1 1 Hi any1 any2
2 1 Hi any1 any2
3 2 Bye any1 any2
4 3 Later any1 any2
5 3 Later any1 any2
6 3 Later any1 any2
7 any2
条件:
- 在 dtblLeft 中,col1 不需要具有唯一值。
- 在 dtblRight 中,col1 具有唯一值。
- 如果 dtblLeft 在 col1 中缺少一个外键,或者它有一个在 dtblRight 中不存在的外键,则将插入空或空字段。
- 加入 col1。
我可以使用常规的 DataTable 操作、LINQ 等。
我试过了,但它删除了重复项:
dtblA.PrimaryKey = new DataColumn[] {dtblA.Columns["col1"]}
DataTable dtblJoined = new DataTable();
dtblJoined.Merge(dtblA, false, MissingSchemaAction.AddWithKey);
dtblJoined.Merge(dtblB, false, MissingSchemaAction.AddWithKey);
编辑 1:
这与我想要的很接近,但它只有一张表中的列(在此 link 找到):
dtblJoined = (from t1 in dtblA.Rows.Cast<DataRow>()
join t2 in dtblB.Rows.Cast<DataRow>() on t1["col1"] equals t2["col1"]
select t1).CopyToDataTable();
编辑 2:
来自link 的答案似乎对我有用,但我不得不对其进行一些更改,如下所示:
DataTable targetTable = dtblA.Clone();
var dt2Columns = dtblB.Columns.OfType<DataColumn>().Select(dc =>
new DataColumn(dc.ColumnName, dc.DataType, dc.Expression, dc.ColumnMapping));
var dt2FinalColumns = from dc in dt2Columns.AsEnumerable()
where targetTable.Columns.Contains(dc.ColumnName) == false
select dc;
targetTable.Columns.AddRange(dt2FinalColumns.ToArray());
var rowData = from row1 in dtblA.AsEnumerable()
join row2 in dtblB.AsEnumerable()
on row1["col1"] equals row2["col1"]
select row1.ItemArray.Concat(row2.ItemArray.Where(r2 => row1.ItemArray.Contains(r2) == false)).ToArray();
foreach (object[] values in rowData)
targetTable.Rows.Add(values);
我还发现了这个link,我可能会尝试一下,因为它看起来更简洁。
编辑 3(2013 年 11 月 18 日):
更新了表格以反映更多情况。
【问题讨论】:
-
这也是自然连接。告诉我们当 dtblA 有 '4' 而 dtblB 没有时应该发生什么。
-
以防万一你错过了关于同一问题的其他帖子Check hereand here
-
更新为显示 dtblA 为 4
-
"left OUTER join" 表示在 dtblLeft 中显示所有 col1 条目,这些条目在 dtblRight 中的 col1 中不存在。您可以阅读“OUTER JOIN”,例如“不在加入/匹配另一个表的条目组中”。