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

C# 如何使用公共列在C中对2个或更多数据表进行完全外部联接,c#,datatable,C#,Datatable,我需要用一个公共列合并/连接C上的数据表 我知道有很多关于同一主题的例子和问题。不过,我还没有找到任何能回答我问题的答案 下面是我正在使用的代码 该代码仅允许基于datatable上的数据的一个公共列。我需要一个公共列,但它需要考虑其他帐户中可以使用的任何其他帐户,并将其添加到公共列中。 此外,该代码只允许合并2个数据表。我需要合并31个数据表,每月每天合并1个数据表 我有一个每月每天的数据表,如dt_docDAY01、dt_docDAY02、dt_docDAY03等 每个datatable都包

我需要用一个公共列合并/连接C上的数据表

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

下面是我正在使用的代码

该代码仅允许基于datatable上的数据的一个公共列。我需要一个公共列,但它需要考虑其他帐户中可以使用的任何其他帐户,并将其添加到公共列中。 此外,该代码只允许合并2个数据表。我需要合并31个数据表,每月每天合并1个数据表

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

每个datatable都包含一个账号account和一个余额,存储在一列中,该列引用了DAY01、DAY02等日期

您能告诉我如何更改代码以便包括所有表中的所有帐户吗

还有,我将如何合并这段代码中的所有数据表,这样我就不必运行同一段代码31次

" 字符串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

Account# | Day01 1234 | 11 4567 | 22 0909 | 33 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 表2

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

Account# | Day03 1234 | 13 7777 | 44 预期成果合并表

表1

Account# | Day01 1234 | 11 4567 | 22 0909 | 33 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

这需要处理如下,所有的表不能用魔术连接在一起,让我们取一个较小的样本集:

表1 dt1-账户|第01天 表2 dt2-账户|第02天 表3 dt3-账户|第03天 表4 dt4-账户|第04天 上述操作的结果将是可计算的

还可以使用Nuget实用程序Fastmember,使用匿名类型的IEnumerable将其转换为DataTable


< P>需要处理如下,所有表不能用魔术连接在一起,让我们取一个较小的样本集:

表1 dt1-账户|第01天 表2 dt2-账户|第02天 表3 dt3-账户|第03天 表4 dt4-账户|第04天 上述操作的结果将是可计算的

还可以使用Nuget实用程序Fastmember,使用匿名类型的IEnumerable将其转换为DataTable


@Infost,您正在尝试执行SQL语言中的完全外部联接。在搜索时,我指出了这一答案,并将其应用于两个以上的表格:

从这样的一个例子开始:

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

}
输出是

Account Day01 Day02 Day03 1234 11 12 13 4567 22 909 33 34 5578 99 65 34 7777 44
@Infost,您正在尝试执行SQL语言中的完全外部联接。在搜索时,我指出了这一答案,并将其应用于两个以上的表格:

从这样的一个例子开始:

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

}
输出是

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

@GerardoGrignoli谢谢你的否决票,非常有用,不是。这个内部连接示例如何帮助我连接两个以上的表?你可以将表1和表2连接到表12。然后将表12和表3连接到表123,依此类推。您正在寻找外部联接,而不是内部联接。所以你可以用这个来代替:@GerardoGrignoli谢谢你的否决票,非常有用,不是。这个内部连接示例如何帮助我连接两个以上的表?你可以将表1和表2连接到表12。然后将表12和表3连接到表123,依此类推。您正在寻找外部联接,而不是内部联接。所以你可以用这个来代替:Gerardo,这看起来很完美,但是我无法正确编译函数。我在这一行有一个意外的字符var table123=fullouterjoinDataTable1,table2,table3;。我在类中也有错误,但它是通过您的编辑修复的。您使用的是什么.net框架?哪一行出现了什么编译错误?Gerardo,这段代码运行得很好。我重新键入了有编译问题的行,它工作得非常好。非常感谢您的帮助。Gerardo,似乎99%的数据与此代码正确合并。有一些数据会遇到0。合并前数据正常。你有什么建议吗?例如,合并前的金额为2537.5,合并后的金额为0。Gerardo,这看起来很完美,但我无法正确编译函数。我在这一行有意外字符var table123=fullouterjoinDataTable1,table2,table3;。我在类中也有错误,但它是通过您的编辑修复的。您使用的是什么.net框架?哪一行出现了什么编译错误?Gerardo,这段代码运行得很好。我重新键入了有编译问题的行,它工作得非常好。非常感谢您的帮助。Gerardo,似乎99%的数据与此代码正确合并。有一些数据会遇到0。合并前数据正常。你有什么建议吗?例如,合并前金额为2537.5,合并后金额为0。您好。最后,您能否提供有关如何将此列表数据返回到数据表的详细信息?您好 最后,您能提供更多关于如何将列表数据返回到数据表的信息吗?