一尘不染

Linq-在多个(OR)条件下左联接

c#

我需要在多个条件为ORs而不是ANDs 的情况下进行左联接。我已经找到了许多后者的样本,但是正在努力为我的情况找到正确的答案。

from a in tablea
join b in tableb on new { a.col1, a.col2 } equals new { b.col1, b.col2 }
group a by a into g
select new () { col1 = a.col1, col2 = a.col2, count = g.Count() }

对于必须满足所有条件的联接非常有用。我需要获得加入才能匹配on a.col1 = b.col1 OR a.col2 = b.col2

我知道这一定很容易,但是我对此空白了!

编辑:

为了提供更多信息,查询的目的是获得一个包含“ a”中所有字段以及“
b”中匹配记录的计数的投影。我已经修改了上面的示例,以尝试说明我的追求。当我使用上述方法进行上述操作时,乔恩·斯凯特(Jon
Skeet)指出,我从a获取所有记录的计数,而不是b中相关记录的计数。

基本的左联接可以正常工作:

from a in tablea
from b in tableb
.Where( b => ( a.col1 == b.col1 || a.col2 == b.col2))
.DefaultIfEmpty()
select new { col1 = a.col1, col2 = a.col2 }

如果我修改它以添加如下分组

from a in tablea
from b in tableb
.Where( b => ( a.col1 == b.col1 || a.col2 == b.col2))
.DefaultIfEmpty()
group a by a.col1 into g
select new { col1 = g.Key, count = g.Count() }

我正在获取从a返回的记录数-而不是b中匹配的记录数。

编辑:

我给乔恩答案-我解决了计数问题-我还没意识到我可以用lamda来过滤计数(g.Count(x => x != null))。另外,我需要将b按a分组而不是像上面那样按a分组。这样可以给出正确的结果,但是SQL效率不如我手工编写,因为它添加了相关的子查询-
如果有人可以建议一种更好的编写方式来模拟以下SQL,我将不胜感激!

select a.col1, count(b.col1)
from tablea a
left join tableb b
on a.col1 = b.col1
or a.col2 = b.col2
group by a.col1

阅读 343

收藏
2020-05-19

共1个答案

一尘不染

LINQ仅直接支持等联接。如果要进行任何其他类型的联接,则基本上需要交叉联接和where

from a in tablea
from b in tableb
where a.col1 == b.col1 || a.col2 == b.col2
select ...

可能值得检查生成的SQL的外观和查询计划的外观。可能有更有效的方法,但这可能是 最简单的 方法。

2020-05-19