SQL到LINQ - 内连接之前的左连接

时间:2018-03-14 21:32:55

标签: c# linq join sql-to-linq-conversion

所以我有一个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;

我尝试了几种不同的方法,但我不断将#34; Object引用设置为对象的实例" qd.PostageId上的错误。

LINQ对我来说是一个新手,我喜欢学习它,所以对此的任何帮助都将非常感激。谢谢!

2 个答案:

答案 0 :(得分:2)

来自我的SQL conversion recipe

  1. JOIN条件并非所有与AND进行的相同测试都必须使用加入外的where子句或跨产品(from来处理。 。from ...)然后where
  2. JOIN两个表之间多个AND ed等式测试的条件应该转换为匿名对象
  3. LEFT JOIN使用into joinvariable 进行模拟,然后从{{1>} joinvariable 进行另一次<{1}}
  4. from条款的顺序并不会改变您翻译的方式:

    .DefaultIfEmpty()

    但是,因为JOINvar 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 JOIN INNER JOINNULL中对于不匹配的行永远不会匹配任何行PostageId,它也等同于TableB,其翻译为:

    TableC

答案 1 :(得分:1)

使用:

IConnectableObservable

您的查询使用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子句,它实际上将作为INNER JOIN运行。 如果您与tc.PostageCode = 'Package'子句中的表格中的列值进行比较(并且没有WHERE条款,而您没有与OR进行比较)那么到达该表的所有联接都将被视为NULL)。

如果INNERTableB(这就是您使用null vs LEFT OUTER JOIN的原因),该条款将永远不会 - 所以你应该这样做只需使用INNER JOIN即可使问题更简单。