为什么GroupJoin没有留下外连接?

时间:2013-07-19 09:15:30

标签: c# linq

  

GroupJoin方法在关系数据库中没有直接的等价物   术语,但它实现了内部连接的超集和左外部   连接。左外连接是一个返回该连接的每个元素的连接   第一个(左)数据源,即使它没有相关元素   其他数据来源。

我认为GroupJoin相当于左连接。因为外部的所有元素都将返回内部匹配项的集合。如果在inner中找不到匹配的项,则空集合将与外部元素配对。

但为什么msdn会这么说?

我已阅读GroupJoin和Join的源代码。 MarcinJuraszek提供了一个例子。但我认为我们可以使用以下代码。

Users.GroupJoin(Cars,user=>id,Car=>userId,(user,cars)=>
if(cars.count==0)
{
//John -- NULL
}
else
{
//Ted  -- [ 2, 3 ]
}
return result;
);

GroupJoin的原始逻辑:

Lookup<TKey, TInner> lookup = Lookup<TKey, TInner>.CreateForJoin(inner, innerKeySelector, comparer);
foreach (TOuter current in outer)
{
    yield return resultSelector(current, lookup[outerKeySelector(current)]);
}

我们也可以重写一个LeftJoin:

Lookup<TKey, TInner> lookup = Lookup<TKey, TInner>.CreateForJoin(inner, innerKeySelector, 
foreach (TOuter current in outer)
{
    yield return resultSelector(current, lookup[outerKeySelector(current)].DefaultIfEmpty());
}

2 个答案:

答案 0 :(得分:9)

考虑以下情况:

TableA - Users

id -- name
1  -- Tom
2  -- John
3  -- Ted

TableB - Cars

id -- userId
1  -- 1
2  -- 3
3  -- 3

用户名和车辆ID的标准LEFT JOIN将返回:

name -- carId
Tom  -- 1
John -- NULL
Ted  -- 2
Ted  -- 3

使用GroupJoin,您将获得:

name -- carId
Tom  -- [ 1 ]
John -- [ ]
Ted  -- [ 2, 3 ]

看到区别?

在SQL中,左侧标识显示为存在与JOIN条件匹配的正确项目的次数。

GroupJoin上,您将获得一次左侧项目和一组符合JOIN条件的右侧项目。

答案 1 :(得分:1)

我会添加评论,但我的代表还不够高。

Marcin是正确的,你的问题的简单答案是; 是的,你可以像GroupJoin一样使左外连接返回结果,但为什么呢?

GroupJoin执行左外连接,然后组合结果。左外连接只会返回一个列表(根据Marcin的例子)而不进行任何分组,如果你真的想要,你可以做,但(无论出于什么原因)你可能不想这样做。

编辑:拼写