C#-Linq-使用Linq实现SQL的全连接

使用Linq实现SQL的全连接

2012-11-19 23:00  imyang  阅读(1874)  评论(0)  编辑 收藏

在stackoverflow上看到关于这个问题的讨论,打算记录下来。

关于全连接(Full Outer Join),Linq并不支持,所以就需要使用其它方法来实现,就像不支持全连接的数据库一样,先使用内连接找出公共的部分,然后分别找出左连接和右连接的部分,把这三部分的结果UNION一下,即可得到全连接的效果。

看问题:

ID  FirstName

--  ---------

 1  John

 2  Sue

ID  LastName

--  --------

 1  Doe

 3  Smith

显示下面的结果:

ID  FirstName  LastName

--  ---------  --------

 1  John       Doe

 2  Sue

 3             Smith

实现方法一:

先找出左连接的结果,再找出右连接的结果,然后把这两个结果UNION即可,UNION时会自动把重复的数据过滤掉。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

var firstNames = new[]

{

    new { ID = 1, Name = "John" },

    new { ID = 2, Name = "Sue" },

};

var lastNames = new[]

{

    new { ID = 1, Name = "Doe" },

    new { ID = 3, Name = "Smith" },

};

var leftOuterJoin = from first in firstNames

                    join last in lastNames

                    on first.ID equals last.ID

                    into temp

                    from last in temp.DefaultIfEmpty(new { first.ID, Name = default(string) })

                    select new

                    {

                        first.ID,

                        FirstName = first.Name,

                        LastName = last.Name,

                    };

var rightOuterJoin = from last in lastNames

                     join first in firstNames

                     on last.ID equals first.ID

                     into temp

                     from first in temp.DefaultIfEmpty(new { last.ID, Name = default(string) })

                     select new

                     {

                         last.ID,

                         FirstName = first.Name,

                         LastName = last.Name,

                     };

var fullOuterJoin = leftOuterJoin.Union(rightOuterJoin);

方法二:

得到左连接的数据,再从右连接的数据中把左连接的数据排除掉,两者的数据Concat一下即可

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

var firstNames = new[]

{

    new { ID = 1, Name = "John" },

    new { ID = 2, Name = "Sue" },

};

var lastNames = new[]

{

    new { ID = 1, Name = "Doe" },

    new { ID = 3, Name = "Smith" },

};

var leftData = (from first in firstNames

                join last in lastNames on first.ID equals last.ID into temp

                from last in temp.DefaultIfEmpty(new { first.ID, Name = default(string) })

                select new

                {

                    first.ID,

                    FirstName = first.Name,

                    LastName = last.Name,

                });

var rightRemainingData = (from in lastNames

                          where !(from in leftData select a.ID).Contains(r.ID)

                          select new

                          {

                              r.ID,

                              FirstName = default(string),

                              LastName = r.Name

                          });

var fullOuterjoinData = leftData.Concat(rightRemainingData);

以上两种方法,其实是同一种方式来实现全连接的,只是第二次拿出的数据有所不同。

以上,希望对大家有所帮助。

原文地址:https://www.cnblogs.com/grj001/p/12223278.html