首页 > 后端开发 > C++ > 如何在 C# 中有效地将具有不同架构的多个 DataTable 合并到单个 DataTable 中?

如何在 C# 中有效地将具有不同架构的多个 DataTable 合并到单个 DataTable 中?

Barbara Streisand
发布: 2024-12-29 13:50:10
原创
309 人浏览过

How can I efficiently merge multiple DataTables with varying schemas into a single DataTable in C#?

将多个具有变量模式的 DataTable 组合成一个表

为了解决将多个 DataTable 组合成一个表的问题,我们推荐一种有效的方法来有效处理改变列结构和行对齐。

快速解决方案

以下 C# 代码片段提供简单的方法:

public static DataTable MergeTables(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)
    {
        // join rows with repeating primary key columns
        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;
}
登录后复制

用法

要使用 MergeTables 方法,请按照以下步骤操作:

  1. 定义输入 DataTable 列表。
  2. (可选)如果表共享公共主键,则指定主键列的名称键。
  3. 使用表列表和主键列(如果适用)调用 MergeTables 方法。
  4. 该方法返回包含合并数据的单个 DataTable,处理列结构中的任何差异以及行对齐。

示例

考虑以下示例DataTables:

DataTable1 (Columns: c1, c2, c3, c4)
| c1 | c2 | c3 | c4 |
|---|---|---|---|
| 1 | 8500 | abc | A |
| 2 | 950 | cde | B |
| 3 | 150 | efg | C |
| 4 | 850 | ghi | D |
| 5 | 50 | ijk | E |

DataTable2 (Columns: c1, c5, c6, c7)
| c1 | c5 | c6 | c7 |
|---|---|---|---|
| 1 | 7500 | klm | F |
| 2 | 900 | mno | G |
| 3 | 150 | opq | H |
| 4 | 850 | qrs | I |
| 5 | 50 | stu | J |

DataTable3 (Columns: c1, c8, c9, c10)
| c1 | c8 | c9 | c10 |
|---|---|---|---|
| 1 | 7500 | uvw | K |
| 2 | 900 | wxy | L |
| 3 | 150 | yza | M |
| 4 | 850 | ABC | N |
| 5 | 50 | CDE | O |
登录后复制

要合并这三个表,我们可以调用 MergeTables 方法,如下所示:

var tables = new[] { DataTable1, DataTable2, DataTable3 };
DataTable mergedTable = MergeTables(tables, "c1");
登录后复制

mergedTable 将包含三个输入表中的所有行,其中由公共主键列“c1”对齐的列。行中的任何缺失值都将从具有相同主键值的第一个非空行填充。

以上是如何在 C# 中有效地将具有不同架构的多个 DataTable 合并到单个 DataTable 中?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板