zoukankan      html  css  js  c++  java
  • 使用Linq实现SQL的全连接

    在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时会自动把重复的数据过滤掉。

                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一下即可

                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 r in lastNames
                                          where !(from a in leftData select a.ID).Contains(r.ID)
                                          select new
                                          {
                                              r.ID,
                                              FirstName = default(string),
                                              LastName = r.Name
                                          });
    
                var fullOuterjoinData = leftData.Concat(rightRemainingData);
    

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

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

  • 相关阅读:
    如何使不同时区的时间与京8区一致?(JS实现)
    再论递归
    如何实现keep-alive
    [小tips]使用vscode,根据vue模板文件生成代码
    gulp-load-task 解决 gulpfile.js 过大的问题
    《Vue 编程房内考》
    前端开发笔试题汇总
    HTTP状态码及其含义 503 500 401 200 301 302
    IE, FF, Safari前端开发常用调试工具
    DOCTYPE与浏览器模式详解(标准模式&混杂模式)
  • 原文地址:https://www.cnblogs.com/zhaohuayang/p/2778178.html
Copyright © 2011-2022 走看看