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

Inf*_*ost 0 c# datatable

我需要在C#上使用公共列合并/连接数据表.

我知道很多例子以及有关同一主题的问题.我没有找到任何回答我的问题.

以下是我正在使用的代码.

该代码仅允许基于on datatable数据的一个公共列.我需要一个公共列,但需要考虑任何其他"帐户#"可以在另一个数据表中使用并将其添加到公共列中.

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

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

每个数据表包含一个帐号"帐号#"和一个存储在一列中的余额,参考当天"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();`
Run Code Online (Sandbox Code Playgroud)

表格1

Account#    |    Day01
1234        |      11
4567        |      22
0909        |      33

表2

Account#    |    Day02
1234        |      12
0909        |      34
5578        |      99
0065        |      34

表3

Account#    |    Day03
1234        |      13
7777        |      44

预期结果合并表

表格1

Account#    |    Day01     |   Day02     |   Day03
1234        |      11      |      12     |     13
4567        |      22      |       0     |     0
0909        |      33      |      34     |     0
5578        |      0       |      99     |     0
0065        |      0       |      34     |     0
7777        |      0       |      0      |     44

Ger*_*oli 5

@Infost,你正在尝试用SQL语言做什么full outer join.在SO上搜索指向这个答案/sf/answers/1178246751/我已经适应了超过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);
Run Code Online (Sandbox Code Playgroud)

你可以加入他们调用以下函数:

var table123 = FullOuterJoinDataTables(table1, table2, table3);
Run Code Online (Sandbox Code Playgroud)

这是功能来源:

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(); }

}
Run Code Online (Sandbox Code Playgroud)

输出是

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