I have web searched but I still cant find a simple answer. Can someone please explain (in simple English) what a GroupJoin
is? How is it different from a regular inner Join
? Is it commonly used? Is it only for method syntax? What about query syntax? A c# code example would be nice.
相关问题
- Sorting 3 numbers without branching [closed]
- Graphics.DrawImage() - Throws out of memory except
- Why am I getting UnauthorizedAccessException on th
- 求获取指定qq 资料的方法
- How to know full paths to DLL's from .csproj f
According to eduLINQ:
The only difference is in return statement:
Join:
GroupJoin:
Read more here:
Reimplementing LINQ to Objects: Part 19 - Join
Reimplementing LINQ to Objects: Part 22 - GroupJoin
Behaviour
Suppose you have two lists:
When you
Join
the two lists on theId
field the result will be:When you
GroupJoin
the two lists on theId
field the result will be:So
Join
produces a flat (tabular) result of parent and child values.GroupJoin
produces a list of entries in the first list, each with a group of joined entries in the second list.That's why
Join
is the equivalent ofINNER JOIN
in SQL: there are no entries forC
. WhileGroupJoin
is the equivalent ofOUTER JOIN
:C
is in the result set, but with an empty list of related entries (in an SQL result set there would be a rowC - null
).Syntax
So let the two lists be
IEnumerable<Parent>
andIEnumerable<Child>
respectively. (In case of Linq to Entities:IQueryable<T>
).Join
syntax would bereturning an
IEnumerable<X>
where X is an anonymous type with two properties,Value
andChildValue
. This query syntax uses theJoin
method under the hood.GroupJoin
syntax would bereturning an
IEnumerable<Y>
where Y is an anonymous type consisting of one property of typeParent
and a property of typeIEnumerable<Child>
. This query syntax uses theGroupJoin
method under the hood.We could just do
select g
in the latter query, which would select anIEnumerable<IEnumerable<Child>>
, say a list of lists. In many cases the select with the parent included is more useful.Some use cases
1. Producing a flat outer join.
As said, the statement ...
... produces a list of parents with child groups. This can be turned into a flat list of parent-child pairs by two small additions:
The result is similar to
Note that the range variable
c
is reused in the above statement. Doing this, anyjoin
statement can simply be converted to anouter join
by adding the equivalent ofinto g from c in g.DefaultIfEmpty()
to an existingjoin
statement.This is where query (or comprehensive) syntax shines. Method (or fluent) syntax shows what really happens, but it's hard to write:
So a flat
outer join
in LINQ is aGroupJoin
, flattened bySelectMany
.2. Preserving order
Suppose the list of parents is a bit longer. Some UI produces a list of selected parents as
Id
values in a fixed order. Let's use:Now the selected parents must be filtered from the parents list in this exact order.
If we do ...
... the order of
parents
will determine the result. If the parents are ordered byId
, the result will be parents 2, 3, 4, 7. Not good. However, we can also usejoin
to filter the list. And by usingids
as first list, the order will be preserved:The result is parents 3, 7, 2, 4.