65.9K
CodeProject 正在变化。 阅读更多。
Home

C#全外连接两个DataTable

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.90/5 (8投票s)

2009年6月20日

GPL3

2分钟阅读

viewsIcon

102972

本文解释了如何使用 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`' 使用以下顺序连接两个表

  1. 创建空数据表 - '`dtResult`',它将填充结果集。
  2. 将左侧数据表的列名添加到 '`dtResult`' 数据表。
  3. 将右侧数据表的列名添加到 '`dtResult`' 数据表,不包括右侧数据表的主键列。
  4. 将左侧数据表数据填充到 '`dtResult`',循环遍历左侧数据表的每一行
  5. 使用 '`DataSetToArrayList`' 方法将左侧表的主键值存储在数组列表 '`var`' 中  
  6. 填充右侧表数据,其中键不在左侧表中。
  7. 填充右侧表数据,通过循环遍历每一行中的列来连接行。
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日:初始帖子
© . All rights reserved.