SQL 到 LINQ - 内部联接之前的左联接

SQL to LINQ - Left Join Before Inner Join

所以我有一个 SQL 查询,我想将其转换为 LINQ。

这里是查询:

SELECT *
FROM DatabaseA.SchemaA.TableA ta
    LEFT OUTER JOIN DatabaseA.SchemaA.TableB tb
    ON tb.ShipId = ta.ShipId
    INNER JOIN DatabaseA.SchemaA.TableC tc
    ON tc.PostageId= tb.PostageId
WHERE tc.PostageCode = 'Package'
      AND ta.MailId = 'Specification'

我正在努力解决的问题是我似乎无法弄清楚如何在内部联接之前在 LINQ 中执行左联接,因为至少我不太清楚在 LINQ 中执行左联接。

我发现了很多 LINQ 内部联接然后是左联接的示例,但没有找到左联接然后是内部联接的示例。

如果有帮助,这是我一直在使用的 LINQ 查询:

var query = from m in tableA
join s in tableB on m.ShipId equals s.ShipId into queryDetails
from qd in queryDetails.DefaultIfEmpty()
join p in tableC on qd.PostageId equals p.PostageId
where m.MailId == "Specification" && p.PostageCode == "Package"
select m.MailId;

我已经尝试了几种不同的方法,但我在 qd.PostageId.

上一直收到 "Object reference not set to an instance of an object" 错误

LINQ 对我来说很新,我喜欢学习它,所以对此的任何帮助将不胜感激。谢谢!

使用:

var query = from m in tableA
join s in tableB on m.ShipId equals s.ShipId
join p in tableC on s.PostageId equals p.PostageId
where m.MailId == "Specification" && p.PostageCode == "Package"
select m.MailId;

您的查询使用了 LEFT OUTER JOIN 但它并不需要它。

实际上,由于您的 tc.PostageCode = 'Package' 子句,它将作为 INNER JOIN 发挥作用。 如果您与 WHERE 子句中的 table 中的列值进行比较(并且没有 OR 子句并且您没有与 NULL 进行比较) 然后有效地 all 加入到那个 table 将被视为 INNER).

如果 TableBnull,该子句将 永远不会 成立(这就是为什么您使用 LEFT OUTER JOININNER JOIN ) - 所以你应该只使用 INNER JOIN 来简化问题。

来自我的 :

  1. JOIN 并非所有与 AND 相等性测试的条件必须使用连接外部的 where 子句或叉积(from .. . from ...) 然后 where
  2. JOIN 两个表之间的多个 ANDed 相等性测试的条件应翻译成匿名对象
  3. LEFT JOIN 是通过使用 into joinvariable 并从 from 中执行另一个 joinvariable[=47= 来模拟的] 其次是 .DefaultIfEmpty().

JOIN 子句的顺序不会改变您翻译它们的方式:

var ans = from ta in TableA
          join tb in TableB on ta.ShipId equals tb.ShipId into tbj
          from tb in tbj.DefaultIfEmpty()
          join tc in TableC on tb.PostageId equals tc.PostageId
          where tc.PostageCode == "Package" && ta.MailId == "Specification"
          select new { ta, tb, tc };

但是,因为LEFT JOININNER JOIN之前执行,然后NULL PostageIdTableB中对于不匹配的行永远不会匹配任何TableC 中的行,它也等同于 INNER JOIN,翻译为:

var ans2 = from ta in tableA
           join tb in tableB on ta.ShipId equals tb.ShipId
           join tc in tableC on tb.PostageId equals tc.PostageId
           where tc.PostageCode == "Package" && ta.MailId == "Specification"
           select new { ta, tb, tc };