C#全外连接两个DataTable






4.90/5 (8投票s)
本文解释了如何使用 C# 连接两个数据表并将结果集放入新的数据表中。 这里,没有使用数据库访问来完成此操作。
引言
我意识到 ADO.NET 不支持在其数据集/数据表上使用 SQL 语句。 需求是完全外连接两个数据表,给定两个数据表的主键。
本文解释了如何使用完全外连接连接数据表,并将结果集放入使用 ADO.NET 的新数据表中,C#。
背景
完全外连接结合了左外连接和右外连接的结果。 连接的表将包含来自两个表的所有记录,并在任一侧缺少匹配项时填充 `NULL`。
例如,这允许我们查看每个属于部门的员工和每个有员工的部门,还可以查看每个不属于部门的员工和每个没有员工的部门。
示例完全外连接
SELECT *
FROM employee
FULL OUTER JOIN department
ON employee.DepartmentID = department.DepartmentID
员工。 LastName |
员工。 部门ID |
部门。 部门名称 |
部门。 部门ID |
史密斯 | 34 | 文书 | 34 |
琼斯 | 33 | 工程 | 33 |
罗宾逊 | 34 | 文书 | 34 |
贾斯珀 | NULL | NULL | NULL |
斯坦伯格 | 33 | 工程 | 33 |
拉菲蒂 | 31 | 销售 | 31 |
NULL | NULL | 市场营销 | 35 |
Using the Code
下面的 '`MyJoinMethod`' 使用完全外连接连接两个数据表,并返回一个包含合并结果的数据表,以便暴露给程序中使用的其他方法或用于数据绑定。作为输入,该方法需要合并的两个数据表,我称之为 '`LeftTable`' 和 '`RightTable`' 以及两个表的主键列(即 '`LeftPrimaryColumn`' 和 '`RightPrimaryColumn`')
'`MyJoinMethod`' 还使用 '`DataSetToArrayList`' 方法将给定的数据列返回到数组列表。
public ArrayList DataSetToArrayList(int ColumnIndex, DataTable dataTable)
{
ArrayList output = new ArrayList();
foreach (DataRow row in dataTable.Rows)
output.Add(row[ColumnIndex]);
return output;
}
'`MyJoinMethod`' 使用以下顺序连接两个表
- 创建空数据表 - '`dtResult`',它将填充结果集。
- 将左侧数据表的列名添加到 '`dtResult`' 数据表。
- 将右侧数据表的列名添加到 '`dtResult`' 数据表,不包括右侧数据表的主键列。
- 将左侧数据表数据填充到 '`dtResult`',循环遍历左侧数据表的每一行
- 使用 '`DataSetToArrayList`' 方法将左侧表的主键值存储在数组列表 '`var`' 中
- 填充右侧表数据,其中键不在左侧表中。
- 填充右侧表数据,通过循环遍历每一行中的列来连接行。
public DataTable myJoinMethod(DataTable LeftTable, DataTable RightTable,
String LeftPrimaryColumn, String RightPrimaryColumn)
{
//first create the datatable columns
DataSet mydataSet = new DataSet();
mydataSet.Tables.Add(" ");
DataTable myDataTable = mydataSet.Tables[0];
//add left table columns
DataColumn[] dcLeftTableColumns = new DataColumn[LeftTable.Columns.Count];
LeftTable.Columns.CopyTo(dcLeftTableColumns, 0);
foreach (DataColumn LeftTableColumn in dcLeftTableColumns)
{
if (!myDataTable.Columns.Contains(LeftTableColumn.ToString()))
myDataTable.Columns.Add(LeftTableColumn.ToString());
}
//now add right table columns
DataColumn[] dcRightTableColumns = new DataColumn[RightTable.Columns.Count];
RightTable.Columns.CopyTo(dcRightTableColumns, 0);
foreach (DataColumn RightTableColumn in dcRightTableColumns)
{
if (!myDataTable.Columns.Contains(RightTableColumn.ToString()))
{
if (RightTableColumn.ToString() != RightPrimaryColumn)
myDataTable.Columns.Add(RightTableColumn.ToString());
}
}
//add left-table data to mytable
foreach (DataRow LeftTableDataRows in LeftTable.Rows)
{
myDataTable.ImportRow(LeftTableDataRows);
}
ArrayList var = new ArrayList(); //this variable holds the id's which have joined
ArrayList LeftTableIDs = new ArrayList();
LeftTableIDs = this.DataSetToArrayList(0, LeftTable);
//import righttable which having not equal Id's with lefttable
foreach (DataRow rightTableDataRows in RightTable.Rows)
{
if (LeftTableIDs.Contains(rightTableDataRows[0]))
{
string wherecondition = "[" + myDataTable.Columns[0].ColumnName + "]='"
+ rightTableDataRows[0].ToString() + "'";
DataRow[] dr = myDataTable.Select(wherecondition);
int iIndex = myDataTable.Rows.IndexOf(dr[0]);
foreach (DataColumn dc in RightTable.Columns)
{
if (dc.Ordinal != 0)
myDataTable.Rows[iIndex][dc.ColumnName.ToString().Trim()] =
rightTableDataRows[dc.ColumnName.ToString().Trim()].ToString();
}
}
else
{
int count = myDataTable.Rows.Count;
DataRow row = myDataTable.NewRow();
row[0] = rightTableDataRows[0].ToString();
myDataTable.Rows.Add(row);
foreach (DataColumn dc in RightTable.Columns)
{
if (dc.Ordinal != 0)
myDataTable.Rows[count][dc.ColumnName.ToString().Trim()] =
rightTableDataRows[dc.ColumnName.ToString().Trim()].ToString();
}
}
}
return myDataTable;
}
历史
- 2009年6月20日:初始帖子