c# - 如何使用公共(public)列在 C# 中对 2 个或多个数据表进行完全外部联接

标签 c# datatable

我需要将 C# 上的数据表与公共(public)列合并/连接。

我知道很多例子和关于同一主题的问题。不过,我还没有找到任何能回答我问题的答案。

下面是我正在使用的代码。

该代码仅允许基于数据表上的数据的一个公共(public)列。我需要一个公共(public)列,但它需要考虑可能在另一个数据表中使用的任何其他“帐户#”并将其添加到公共(public)列中。

此外,代码只允许合并 2 个数据表。我需要合并 31 个数据表,以便为一个月中的每一天合并 1 个数据表。

我有一个月中每一天的数据表,dt_docDAY01、dt_docDAY02、dt_docDAY03 等。

每个数据表都包含一个帐号“Account#”和一个存储在“DAY01”、“DAY02”等日期的列中的余额。

你能告诉我如何更改代码,以便我将包含所有表中的所有帐户。

另外,我将如何合并此代码中的所有数据表,因此我不必运行相同的代码 31 次。

'
string id = "账号#";

                var tableJoinedDAY02 = dt_docDAY01_GROUPED.Clone(); // create columns from table1

                // add columns from table2 except id
                foreach (DataColumn column in dt_docDAY02_GROUPED.Columns)
                {
                    if (column.ColumnName != id)
                        tableJoinedDAY02.Columns.Add(column.ColumnName, column.DataType);
                }

                tableJoinedDAY02.BeginLoadData();

                foreach (DataRow row1 in dt_docDAY01_GROUPED.Rows)
                {
                    foreach (DataRow row2 in dt_docDAY02_GROUPED.Rows)
                    {
                        if (row1.Field<string>(id) == row2.Field<string>(id))
                        {
                            var list = row1.ItemArray.ToList(); // items from table1

                           // add items from table2 except id
                            foreach (DataColumn column in dt_docDAY02_GROUPED.Columns)
                                if (column.ColumnName != id)
                                    list.Add(row2[column]);

                            tableJoinedDAY02.Rows.Add(list.ToArray());
                        }
                    }
                }

                    tableJoinedDAY02.EndLoadData();`

表格1

帐号# |第01天
第1234章11
4567 | 22
0909 | 33

表2

帐号# |第02天
第1234章12
0909 | 34
5578 | 99
0065 | 34

表3

帐号# |第03天
第1234章13
7777 | 44

预期结果合并表

表格1

帐号# |第一天 |第02天 |第03天
第1234章11 | 12 | 13
4567 | 22 | 0 | 0
0909 | 33 | 34 | 0
5578 | 0 | 99 | 0
0065 | 0 | 34 | 0
7777 | 0 | 0 | 44

最佳答案

@Infost,您正在尝试执行 SQL 语言中的 full outer join 。在 SO 上搜索指向这个答案 https://stackoverflow.com/a/16832096/97471 ,我已经适应了 2 个以上的表:

从像这样的 MVCE 开始:

DataTable table1 = new DataTable();
table1.Columns.Add("Account", typeof(int));
table1.Columns.Add("Day01", typeof(decimal));

table1.Rows.Add(1234, 11);
table1.Rows.Add(4567, 22);
table1.Rows.Add(0909, 33);

DataTable table2 = new DataTable();
table2.Columns.Add("Account", typeof(int));
table2.Columns.Add("Day02", typeof(decimal));

table2.Rows.Add(1234, 12);
table2.Rows.Add(0909, 34);
table2.Rows.Add(5578, 99);
table2.Rows.Add(0065, 34);

DataTable table3 = new DataTable();
table3.Columns.Add("Account", typeof(int));
table3.Columns.Add("Day03", typeof(decimal));

table3.Rows.Add(1234, 13);
table3.Rows.Add(7777, 44);

您可以调用以下函数加入它们:
var table123 = FullOuterJoinDataTables(table1, table2, table3);

下面是函数源码:
DataTable FullOuterJoinDataTables(params DataTable[] datatables) // supports as many datatables as you need.
{
    DataTable result = datatables.First().Clone();

    var commonColumns = result.Columns.OfType<DataColumn>();

    foreach (var dt in datatables.Skip(1))
    {
        commonColumns = commonColumns.Intersect(dt.Columns.OfType<DataColumn>(), new DataColumnComparer());
    }

    result.PrimaryKey = commonColumns.ToArray();

    foreach (var dt in datatables)
    {
        result.Merge(dt, false, MissingSchemaAction.AddWithKey);
    }

    return result;
}

/* also create this class */
public class DataColumnComparer : IEqualityComparer<DataColumn>
{
    public bool Equals(DataColumn x, DataColumn y) { return x.Caption == y.Caption; }

    public int GetHashCode(DataColumn obj) { return obj.Caption.GetHashCode(); }

}

输出是

账户 Day01 Day02 Day03
1234 11 12 13
4567 22
909 33 34
5578 99
65 34
7777 44

关于c# - 如何使用公共(public)列在 C# 中对 2 个或多个数据表进行完全外部联接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39009926/

相关文章:

php - 使用 php 显示我的数据库中的付费项目数量

预期的 C# 方法名称 - 多线程

php - Symfony3 数据表无法呈现

c# - 如何使用 Linq 返回列值已更改的列表或可枚举行

c# - 如何将数据库值获取到 c#.net 中的下拉菜单

javascript - 数据表根据另一个值计算列总计

c# - 如何从文本文件中读取数百万行并快速插入到表中

c# - 在 ASP.NET Core 2.1 中更改 IdentityUser 类型

c# - 设置动态创建的 asp :button 的 OnClick 属性

c# - 使用 MongoDB C# 驱动程序 2.2 对嵌套字段进行强类型查询