简体   繁体   English

在C#中使用Linq进行完全外部联接3数据表

[英]full outer join 3 DataTables using Linq in c#

/*See last 3 lines of my question for my explanation of how my question is different than the suggested possible duplicate. / *请参阅问题的后三行,以解释问题与建议的重复内容有何不同。 */ * /

I'm trying to join 3 DataTables together using Linq. 我正在尝试使用Linq将3个DataTables连接在一起。

Let's say the DataTable names are table1, table2, and table3 Let's say each Datatable has 6 columns, and the column names are col1, col2, col3, col4, col5, and col6. 假设DataTable的名称为table1,table2和table3,假设每个Datatable有6列,而列的名称为col1,col2,col3,col4,col5和col6。

I want to join these tables where col1,col2,col3, and col4 match. 我想加入col1,col2,col3和col4匹配的这些表。

I want to append columns 5 and 6 from tables 2 and 3 to table1, resulting in a table4 that has 10 columns and all records whether matching or not (null if not matching). 我想将表2和3的第5列和第6列追加到table1,导致一个table4包含10列并且所有记录是否匹配(如果不匹配则为null)。

I've researched this most of the morning and can't seem to wrap my head around it. 我在整个上午的大部分时间里都在研究,似乎无法绕过它。 I was going to put my attempt at the code below but I think all it would do is confuse people. 我本想尝试下面的代码,但我认为这样做只会使人们感到困惑。 Thank you in advance for any help. 预先感谢您的任何帮助。 I hope I gave enough info. 我希望我提供了足够的信息。

EDIT: I'm going to put my attempt at the code below. 编辑:我要把我的尝试放在下面的代码。 I couldn't even get any join to work, much less all tables: 我什至无法加入任何工作,更不用说所有表格了:

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

my question is unique from the suggested duplicate due to the below: 1. that question addresses joining lists not DataTables 2. that question addresses joining based off matching one column not multiple 由于以下原因,我的问题与建议的重复项不同:1.该问题解决了联接列表而不是DataTables 2.该问题解决了基于匹配一列而不是多个列的联接问题

I'm not sure whether you are using IEnumerable or IQueryable, the code will be similar. 我不确定您使用的是IEnumerable还是IQueryable,代码是否相似。

A join on three tables is easier when written in query syntax, than when written in method syntax. 用查询语法编写时,对三个表的联接比用方法语法编写时更容易。 See How to perform Join between multiple tables in LINQ lambda There you'll see how to write a join on three tables in method syntax. 请参阅如何在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,
    }
}

I use anonymous types here. 我在这里使用匿名类型。 One of the advantages of anonymous types is that they use equality by value instead of equality by references. 匿名类型的优点之一是它们使用按值相等而不是按引用相等。 So they are perfect to perform joins on multiple fields. 因此,它们非常适合在多个字段上执行联接。 See: t he joy of anonymous types 请参阅: 匿名类型的喜悦

If you do these joins quite often, consider creating a super class that contains Col1..Col4, or an interface. 如果您经常进行这些连接,请考虑创建一个包含Col1..Col4或接口的超类。 Don't forget to define value equality for this. 不要忘记为此定义值相等。

Addition after comment 评论后添加
One of the comments expressed confusion on the initialisation statements of Table1 / Table2 and Table3. 其中一条评论对Table1 / Table2和Table3的初始化语句表示混乱。

In your question you showed a code example where you used Table1, Table2, Table3. 在您的问题中,您展示了一个代码示例,其中使用了Table1,Table2,Table3。 Apparently you had declared and initialized these variables. 显然,您已经声明并初始化了这些变量。 So I am certain the somewhere in your code you had: 因此,我可以肯定您的代码中的某处:

var Table1 = ...

The only difference was that I wrote: 唯一的区别是我写了:

IEnumerable<Table1Element> Table1 = ...

I did this to make the rest of the code better readable. 我这样做是为了使其余代码更具可读性。 I defined the elements of Table1 to be of type Table1Element . 我将Table1的元素定义为Table1Element类型。 I assumed that if your Table1 contains elements of MyClass you'd know what to replace in my code. 我假设,如果您的Table1包含MyClass元素,您将知道在我的代码中要替换的内容。

End of addition 添加结束

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM