【问题标题】:full outer join 3 DataTables using Linq in c#在 c# 中使用 Linq 完全外连接 3 个数据表
【发布时间】:2018-05-24 10:02:10
【问题描述】:

/*请参阅我的问题的最后 3 行,了解我的问题与建议的可能重复项有何不同。 */

我正在尝试使用 Linq 将 3 个数据表连接在一起。

假设 DataTable 名称是 table1、table2 和 table3 假设每个Datatable有6列,列名分别为col1、col2、col3、col4、col5、col6。

我想加入 col1、col2、col3 和 col4 匹配的这些表。

我想将表 2 和表 3 中的第 5 列和第 6 列附加到表 1,从而得到一个表 4,它有 10 列和所有记录,无论是否匹配(如果不匹配,则为空)。

我早上的大部分时间都在研究这个问题,但似乎无法理解它。我打算尝试下面的代码,但我认为它只会让人们感到困惑。预先感谢您的任何帮助。我希望我提供了足够的信息。

编辑:我将尝试下面的代码。我什至无法加入任何工作,更不用说所有表了:

 var table4 = from one in Table1 join two in Table2 on one.col1 equals two.col1, one.col2 equals two.col2, one.col3 equals two.col3, one.col4 equals two.col4
                       select new { one.col1, two.col1, one.col2, two.col2, one.col3,two.col3,one.col4,two.col4};

由于以下原因,我的问题与建议的重复项不同: 1.该问题涉及加入列表而不是数据表 2.该问题解决了基于匹配一列而不是多列的加入

【问题讨论】:

  • LINQ - Full Outer Join的可能重复
  • @mjwills 不,那是我看的第一个,它正在加入列表,也只加入一列
  • 为什么不用sql,哪个更简单?
  • 标记为重复项中的第二个答案具有通用的完全外连接实现,它也是 MoreLINQ stackoverflow.com/a/13503860/1383168 的一部分,可以与 DataTables 和多个键一起使用

标签: c# linq datatable


【解决方案1】:

我不确定你使用的是IEnumerable还是IQueryable,代码会类似。

用查询语法编写的三个表的连接比用方法语法编写的要容易。请参阅How to perform Join between multiple tables in LINQ lambda 那里您将看到如何在方法语法中编写三个表的连接。

IEnumerable<Table1Element> Table1 = ...
IEnumerable<Table2Element> Table2 = ...
IEnumerable<Table3Element> Table3 = ...

from table1Element in Table1
join table2Element in Table2
    on new
    {
        Col1 = table1Element.Col1,
        Col2 = table1Element.Col2,
        Col3 = table1Element.Col3,
        Col4 = table1Element.Col4,
    }
    equals new
    {
        Col1 = table2Element.Col1,
        Col2 = table2Element.Col2,
        Col3 = table2Element.Col3,
        Col4 = table2Element.Col4,
    }
join table3Element in Table3
    on new
    {
        Col1 = table2Element.Col1,
        Col2 = table2Element.Col2,
        Col3 = table2Element.Col3,
        Col4 = table2Element.Col4,
    }
    equals new
    {
        Col1 = table3Element.Col1,
        Col2 = table3Element.Col2,
        Col3 = table3Element.Col3,
        Col4 = table3Element.Col4,
    }
select new
{
    Col1 = table1Element.Col1,
    Col2 = table1Element.Col2,
    Col3 = table1Element.Col3,
    Col4 = table1Element.Col4,
    // only if required: col5 and col6 from table1
    FromTable1 = new
    {
         Col5 = table1Element.Col5,
         Col6 = table1Element.Col6,
    }
    FromTable2 = new
    {
         Col5 = table2Element.Col5,
         Col6 = table2Element.Col6,
    }
    FromTable3 = new
    {
         Col5 = table3Element.Col5,
         Col6 = table3Element.Col6,
    }
}

我在这里使用匿名类型。匿名类型的优点之一是它们使用值相等而不是引用相等。因此它们非常适合在多个字段上执行连接。见:the joy of anonymous types

如果您经常进行这些连接,请考虑创建一个包含 Col1..Col4 或接口的超类。不要忘记为此定义值相等。

评论后添加
其中一位 cmet 对 Table1/Table2 和 Table3 的初始化语句表示困惑。

在您的问题中,您展示了一个使用 Table1、Table2、Table3 的代码示例。显然您已经声明并初始化了这些变量。 所以我确定你的代码中的某个地方:

var Table1 = ...

唯一的区别是我写的:

IEnumerable<Table1Element> Table1 = ...

我这样做是为了使其余代码更易读。我将Table1 的元素定义为Table1Element 类型。我假设如果您的 Table1 包含 MyClass 的元素,您就会知道在我的代码中替换什么。

添加结束

【讨论】:

  • 这非常有帮助。但是代码的以下部分中的“...”是什么: IEnumerable Table1 = ...
  • 我没有用 VAR 声明这两个表,它们是 DataTables
  • 也许我应该这样做而不是制作数据表。我似乎无法弄清楚这一点
猜你喜欢
  • 2014-08-07
  • 2014-09-14
  • 1970-01-01
  • 2018-05-10
  • 2018-03-04
  • 2015-03-31
  • 2014-03-08
  • 2017-06-10
  • 2018-05-30
相关资源
最近更新 更多