簡體   English   中英

使用左聯接轉換LINQ內聯接

[英]Converting a LINQ Inner join with Left Join

我正在嘗試在查詢中實現左聯接,此刻我得到的是“對象引用未設置為對象的實例”。

該查詢可以作為內部聯接很好地工作,但是盡管找到了匹配項,但我仍想包括左表中的所有行。 我曾嘗試遵循此之前的一些帖子,大部分都引用DefaultIfEmpty(),但我無法弄清楚。

INNER JOIN - SQL
      SELECT TOP (1000) 
      FROM table1 as edc
      inner join table2 as c on edc.Id = c.Id
      inner join table3 as p on p.Id = c.Id
      group by p.Description

內部聯接-SQL

  SELECT TOP (1000) 
  FROM table1 as edc
  inner join table2 as c on edc.Id = c.Id
  left join table3 as p on p.Id = c.Id
  group by p.Description

內部聯接-LINQ

from edc in table1
   join q1 in table2 on __edc.Id equals q1__.Id
   join q2 in _table3 on q2.Id equals q1.Id 
   group q1 by q2.Description
   into grouped
   select new MyObj
   {
     Label = grouped.Key,
     Value = grouped.Count(),
    }

左聯接-LINQ

from edc in table1
       join q1 in table2 on __edc.Id equals q1__.Id
       join q2 in _table3 on q2.Id equals q1.Id  into leftJoin
       from p in leftJoin.DefaultIfEmpty()
       group q1 by p.Description
       into grouped
       select new MyObj
       {
         Label = grouped.Key,
         Value = grouped.Count(),
        }

非常簡單,只需將“從p”更改為“從q2”即可:

   from edc in table1
   join q1 in table2 on __edc.Id equals q1__.Id
   join q2 in _table3 on q2.Id equals q1.Id  into leftJoin
   from q2 in leftJoin.DefaultIfEmpty()
   group q1 by p.Description
   into grouped
   select new MyObj
   {
     Label = grouped.Key,
     Value = grouped.Count(),
    }

考慮以下示例。 我們有3個表,其中table1和table2之間是左連接,table3是第二個左連接。 您需要在兩個聯接上指定DefaultIfEmpty() ,以包括右表中不匹配的行。

public class Item
{
    public int Id { get; set; }

    public string Description { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var table1 = new List<Item>
        {
            new Item {Id = 1, Description = "a"},
            new Item {Id = 2, Description = "b"},
            new Item {Id = 3, Description = "c"},
            new Item {Id = 4, Description = "d"}
        };

        var table2 = new List<Item>
        {
            new Item {Id = 1, Description = "e"},
            new Item {Id = 2, Description = "f"},
            new Item {Id = 4, Description = "g"}
        };

        var table3 = new List<Item>
        {
            new Item {Id = 1, Description = "h"},
            new Item {Id = 4, Description = "h"},
            new Item {Id = 5, Description = "i"},
            new Item {Id = 6, Description = "j"}
        };

        var leftJoin = from t1 in table1
            join t2 in table2 on t1.Id equals t2.Id into firstJoin
            from x in firstJoin.DefaultIfEmpty()
            join t3 in table3 on x?.Id equals t3.Id into secondJoin
            from y in secondJoin.DefaultIfEmpty()
            select new
            {
                Table1Id = t1?.Id,
                Table1Description = t1?.Description,
                Table2Id = x?.Id,
                Table2Description = x?.Description,
                Table3Id =  y?.Id,
                Table3Description = y?.Description
            };

        Console.WriteLine("Left Join:");
        foreach (var i in leftJoin)
        {
            Console.WriteLine($"T1Id: {i.Table1Id}, T1Desc: {i.Table1Description}, " +
                              $"T2Id: {i.Table2Id}, T2Desc: {i.Table2Description}, " +
                              $"T3Id: {i.Table3Id}, T3Desc: {i.Table3Description}");
        }
        Console.WriteLine(string.Empty);

        var grouped = from x in leftJoin
            group x by x.Table3Description
            into group1
            select new
            {
                Label = group1.Key,
                Count = group1.Count()
            };

        Console.WriteLine("Left Join Grouped:");
        foreach (var i in grouped)
        {
            Console.WriteLine($"Label: {i.Label}, Count: {i.Count}");
        }

        Console.ReadLine();
    }
}

運行程序將產生以下輸出:

Left Join:
T1Id: 1, T1Desc: a, T2Id: 1, T2Desc: e, T3Id: 1, T3Desc: h
T1Id: 2, T1Desc: b, T2Id: 2, T2Desc: f, T3Id: , T3Desc:
T1Id: 3, T1Desc: c, T2Id: , T2Desc: , T3Id: , T3Desc:
T1Id: 4, T1Desc: d, T2Id: 4, T2Desc: g, T3Id: 4, T3Desc: h

Left Join Grouped:
Label: h, Count: 2
Label: , Count: 2

希望這可以幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM