首页 文章

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

提问于
浏览
1

所以我有一个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上不断收到“对象引用没有设置为对象的实例”错误 .

LINQ对我来说很新,我喜欢学习它,所以对此有任何帮助都会非常感激 . 谢谢!

2 回答

  • 2

    使用:

    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 子句中的表中的列值进行比较(并且没有 OR 子句,并且您没有与 NULL 进行比较),则实际上 all 连接到该表将被视为 INNER ) .

    如果 TableBnull (这就是为什么你使用 LEFT OUTER JOIN vs INNER JOIN ),那么该子句将为 never - 所以你应该使用 INNER JOIN 来简化问题 .

  • 1

    来自我的SQL conversion recipe

    • JOIN 不是所有与 AND 的相等测试的条件必须使用连接外的 where 子句,或使用叉积( from ... from ...)然后 where 来处理

    • JOIN 条件是两个表之间的多个 AND ed相等测试应该被转换为匿名对象

    • LEFT JOIN 是通过使用 into joinvariable进行模拟,然后从 from 进行另一个,其中是joinvariable,后跟 .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 之前执行,然后 TableB 中的 NULL PostageId 对于不匹配的行将永远不会匹配 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 };
    

相关问题