c# - 在动态列数上连接 2 个数据表

标签 c# linq datatable expression-trees

我正在尝试在动态数量的列上连接两个数据表。我已经得到了下面的代码。问题出在 join 的 ON 语句上。如何根据“joinColumnNames”列表中的列名数量使此动态化。

我想我需要构建某种表达式树,但我找不到任何示例来说明如何使用多个连接列以及使用没有每列属性的 DataRow 对象来执行此操作。

private DataTable Join(List<string> joinColumnNames, DataTable pullX, DataTable pullY)
{
    DataTable joinedTable = new DataTable();

    // Add all the columns from pullX
    foreach (string colName in joinColumnNames)
    {
        joinedTable.Columns.Add(pullX.Columns[colName]);
    }
    // Add unique columns from PullY
    foreach (DataColumn col in pullY.Columns)
    {
        if (!joinedTable.Columns.Contains((col.ColumnName)))
        {
            joinedTable.Columns.Add(col);
        }
    }

    var Join = (from PX in pullX.AsEnumerable()
                join PY in pullY.AsEnumerable() on 
                // This must be dynamic and join on every column mentioned in joinColumnNames
                new { A = PX[joinColumnNames[0]], B = PX[joinColumnNames[1]] } equals new { A = PY[joinColumnNames[0]], B = PY[joinColumnNames[1]] } 
                into Outer
                from PY in Outer.DefaultIfEmpty<DataRow>(pullY.NewRow())
                select new { PX, PY });

    foreach (var item in Join)
    {
        DataRow newRow = joinedTable.NewRow();
        foreach (DataColumn col in joinedTable.Columns)
        {
            var pullXValue = item.PX.Table.Columns.Contains(col.ColumnName) ? item.PX[col.ColumnName] : string.Empty;
            var pullYValue = item.PY.Table.Columns.Contains(col.ColumnName) ? item.PY[col.ColumnName] : string.Empty;
            newRow[col.ColumnName] = (pullXValue == null || string.IsNullOrEmpty(pullXValue.ToString())) ? pullYValue : pullXValue;
        }
        joinedTable.Rows.Add(newRow);
    }

    return joinedTable;
}

添加一个具体示例以使用 3 个联接列(国家/地区、公司和日期 ID)显示输入/输出:

拉X:

Country        Company       DateId    Sales
United States  Test1 Ltd    20160722    $25 

Canada         Test3 Ltd    20160723    $30 

Italy          Test4 Ltd    20160724    $40 

India          Test2 Ltd    20160725    $35 

拉Y:

Country        Company       DateId    Downloads
United States  Test1 Ltd    20160722    500 

Mexico         Test2 Ltd    20160723    300 

Italy          Test4 Ltd    20160724    900 

结果:

Country        Company       DateId    Sales    Downloads
United States  Test1 Ltd    20160722    $25      500 

Canada         Test3 Ltd    20160723    $30  

Mexico         Test2 Ltd    20160723                300 

Italy          Test4 Ltd    20160724    $40      900 

India          Test2 Ltd    20160725    $35      

最佳答案

var Join = 
    from PX in pullX.AsEnumerable()
    join PY in pullY.AsEnumerable()
    on     string.Join("\0", joinColumnNames.Select(c => PX[c]))
    equals string.Join("\0", joinColumnNames.Select(c => PY[c]))
    into Outer
    from PY in Outer.DefaultIfEmpty<DataRow>(pullY.NewRow())
    select new { PX, PY };

另一种方法是将 DataTable 放在 DataSet 中并使用 DataRelation
How To: Use DataRelation to perform a join on two DataTables in a DataSet?

关于c# - 在动态列数上连接 2 个数据表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38778283/

相关文章:

c# - 数据表:数据表结果中的 System.Byte[] 值

jsf-2 - 获取所选素数数据表行的行号

c# - 返回自定义错误 WebApi ASP.NET 5 HttpResponseException 错误状态码

javascript - 将数组传递给 Javascript 数组 C# ASP.NET

c# - 未实现 WCF 接口(interface)

linq - 有谁知道有人在 LINQ-to-Memcached 提供程序上工作?

c# - UWP - 未找到包含提供的指纹的证书

c# - 如何测试 AccessViolationException 的处理

c# - 有没有办法可以延迟LINQ语句中的.Where子句?

javascript - DataTable jQuery 打印自定义元素