LINQ的 - 左加入多(OR)条件(Linq - left join on multiple (O

2019-06-18 09:28发布

我需要做的左连接在哪里的条件是多个条件OR做得相当不是AND秒。 我发现很多后者的样本,但我努力让我的情况下正确的答案。

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”的计数领域的投影。 我修改上面的例子,试图说明我后。 当我使用的方法与上面运行乔恩斯基特注意到我从,而不是在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() }

我得到的从返回的记录计数 - 在b中没有匹配的记录数。

编辑:

我给的答案乔恩-我已经解决了我的问题,计数-我没有意识到我可以用一个LAMDA过滤计数(g.Count(x => x != null)) 另外,我需要B组由而不是由正如我上面了。 这给出正确的结果,但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

Answer 1:

LINQ只直接支持等值连接。 如果你想要做的任何其他形式的加入,你基本上需要一个交叉联接和where

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

这也许值得一试生成的SQL是什么样子,什么查询计划等。 可能有这样做的更有效的方式,但是这可能是最简单的方法。



Answer 2:

根据查询提供者,你可以只选择使用两个FROM子句:

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

其中,如果执行一个数据库,将是多么有效。 如果您在内存中执行(LINQ到对象),这将列举所有可能的组合,这可能是低效的。

精氨酸,Skeeted ;-)。

更高效的LINQ到对象的选择都是可能的。 在join运营商列举每个源只有一次,然后做一个散列连接,所以你可能分裂或从句分成两个单独的连接,然后把他们的工会。 在LINQ一名工会只是没有重复的串联,这样将如下所示:

(from a in tablea
join b in tableb on a.Col1 equals b.Col1
select new {a, b})
.Concat(
from a in tablea
join b in tableb on a.Col2 equals b.Col2
select new {a, b}
).Distinct()

这种方法的工作原理,它只是一个查询,但它有点非显而易见的,即代码的性能特性取决于详细了解LINQ是如何工作的。 就个人而言,如果你想要做的与潜在的多个匹配的散列连接,一个比较明显的工具是ToLookup 。 使用可能如下替代:

var bBy1 = tableb.ToLookup(b=>b.Col1);
var bBy2 = tableb.ToLookup(b=>b.Col2);
var q3 = 
    from a in tablea
    from b in bBy1[a.Col1].Concat(bBy2[a.Col2]).Distinct()
    ...

这种解决方案实际上是短,和它的作品的原因是比较明显的,所以它是一个我喜欢。 只要记住,如果你分裂|| 运营商分成两个单独的查询,如在您需要手动避免重复计算的结果(即使用上述两种情形Distinct )。



文章来源: Linq - left join on multiple (OR) conditions