【问题标题】:C# Join two DataTablesC# 连接两个数据表
【发布时间】:2015-12-12 09:23:44
【问题描述】:

我正在尝试加入两个数据表,它们的行数相同,只有一列。 C# 中有什么奇特的方法可以做到这一点吗?结果,我需要包含两列的数据表,其中第一列的第一行紧挨第二列的第一行。

【问题讨论】:

标签: c#


【解决方案1】:

这是执行此操作的一种方法,所以基本上它使用.Select 的重载,它提供迭代中当前位置的索引,以查找我们当前在@987654323 中查看的table2 中的相应行@。我们为每一行从每个表中生成一个包含两个项目的对象数组。然后我们可以使用LoadDataRow 将它们放入包含两列的目标表中。

// create a target table with 2 columns
DataTable destinationTable = new DataTable();
destinationTable.Columns.Add("Col1");
destinationTable.Columns.Add("Col2");

// select all the rows from the first table, combined with the corresponding value for that row in the second table
var rowsCombined = table1
    .AsEnumerable()
    .Select((row, rowNumber) => new object[] { row[0], table2.Rows[rowNumber][0] });

foreach (var data in rowsCombined)
    destinationTable.LoadDataRow(data, true);       

【讨论】:

    【解决方案2】:

    来自 Tim Schmelter 在此链接上的 ANSWER....

    public static DataTable MergeAll(this IList<DataTable> tables, String   primaryKeyColumn)
    {
        if (!tables.Any())
            throw new ArgumentException("Tables must not be empty", "tables");
        if(primaryKeyColumn != null)
            foreach(DataTable t in tables)
                if(!t.Columns.Contains(primaryKeyColumn))
                    throw new ArgumentException("All tables must have the specified primarykey column " + primaryKeyColumn, "primaryKeyColumn");
    
        if(tables.Count == 1)
            return tables[0];
    
        DataTable table = new DataTable("TblUnion");
        table.BeginLoadData(); // Turns off notifications, index maintenance, and constraints while loading data
        foreach (DataTable t in tables)
        {
            table.Merge(t); // same as table.Merge(t, false, MissingSchemaAction.Add);
        }
        table.EndLoadData();
    
        if (primaryKeyColumn != null)
        {
            // since we might have no real primary keys defined, the rows now might have repeating fields
            // so now we're going to "join" these rows ...
            var pkGroups = table.AsEnumerable()
                .GroupBy(r => r[primaryKeyColumn]);
            var dupGroups = pkGroups.Where(g => g.Count() > 1);
            foreach (var grpDup in dupGroups)
            { 
                // use first row and modify it
                DataRow firstRow = grpDup.First();
                foreach (DataColumn c in table.Columns)
                {
                    if (firstRow.IsNull(c))
                    {
                        DataRow firstNotNullRow =  grpDup.Skip(1).FirstOrDefault(r => !r.IsNull(c));
                        if (firstNotNullRow != null)
                            firstRow[c] = firstNotNullRow[c];
                    }
                }
                // remove all but first row
                var rowsToRemove = grpDup.Skip(1);
                foreach(DataRow rowToRemove in rowsToRemove)
                    table.Rows.Remove(rowToRemove);
            }
        }
    
        return table;
    }
    

    可以这样调用:

    var tables = new[] { tblA, tblB, tblC };
    DataTable TblUnion = tables.MergeAll("c1");
    

    一些样本数据:

    var tblA = new DataTable();
    tblA.Columns.Add("c1", typeof(int));
    tblA.Columns.Add("c2", typeof(int));
    tblA.Columns.Add("c3", typeof(string));
    tblA.Columns.Add("c4", typeof(char));
    
    var tblB = new DataTable();
    tblB.Columns.Add("c1", typeof(int));
    tblB.Columns.Add("c5", typeof(int));
    tblB.Columns.Add("c6", typeof(string));
    tblB.Columns.Add("c7", typeof(char));
    
    var tblC = new DataTable();
    tblC.Columns.Add("c1", typeof(int));
    tblC.Columns.Add("c8", typeof(int));
    tblC.Columns.Add("c9", typeof(string));
    tblC.Columns.Add("c10", typeof(char));
    
    tblA.Rows.Add(1, 8500, "abc", 'A');
    tblA.Rows.Add(2, 950, "cde", 'B');
    tblA.Rows.Add(3, 150, "efg", 'C');
    tblA.Rows.Add(4, 850, "ghi", 'D');
    tblA.Rows.Add(5, 50, "ijk", 'E');
    
    tblB.Rows.Add(1, 7500, "klm", 'F');
    tblB.Rows.Add(2, 900, "mno", 'G');
    tblB.Rows.Add(3, 150, "opq", 'H');
    tblB.Rows.Add(4, 850, "qrs", 'I');
    tblB.Rows.Add(5, 50, "stu", 'J');
    
    tblC.Rows.Add(1, 7500, "uvw", 'K');
    tblC.Rows.Add(2, 900, "wxy", 'L');
    tblC.Rows.Add(3, 150, "yza", 'M');
    tblC.Rows.Add(4, 850, "ABC", 'N');
    tblC.Rows.Add(5, 50, "CDE", 'O');
    

    mergeAll 调用后:

    希望这会有所帮助...

    【讨论】:

      猜你喜欢
      • 2015-05-28
      • 2018-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-12
      • 2020-09-09
      相关资源
      最近更新 更多