Eu pesquisei na web, mas ainda não consigo encontrar uma resposta simples. Alguém pode explicar (em inglês simples) o que GroupJoin
é isso? Como é diferente de um interior regular Join
? É comumente usado? É apenas para sintaxe de método? E a sintaxe da consulta? Um exemplo de código c # seria bom.
c#
linq
linq-to-entities
duyn9uyen
fonte
fonte
Respostas:
Comportamento
Suponha que você tenha duas listas:
Quando você
Join
as duas listas noId
campo, o resultado será:Quando você
GroupJoin
as duas listas noId
campo, o resultado será:Portanto,
Join
produz um resultado simples (tabular) dos valores pai e filho.GroupJoin
produz uma lista de entradas na primeira lista, cada uma com um grupo de entradas unidas na segunda lista.É por isso que
Join
é equivalenteINNER JOIN
no SQL: não há entradas paraC
. EnquantoGroupJoin
é o equivalente aOUTER JOIN
:C
está no conjunto de resultados, mas com uma lista vazia de entradas relacionadas (em um conjunto de resultados SQL, haveria uma linhaC - null
).Sintaxe
Então deixe as duas listas serem
IEnumerable<Parent>
eIEnumerable<Child>
respectivamente. (No caso de Linq to Entities:)IQueryable<T>
.Join
sintaxe seriaretornando um
IEnumerable<X>
onde X é um tipo anônimo com duas propriedadesValue
eChildValue
. Essa sintaxe de consulta usa oJoin
método sob o capô.GroupJoin
sintaxe seriaretornando um
IEnumerable<Y>
onde Y é um tipo anônimo que consiste em uma propriedade do tipoParent
e uma propriedade do tipoIEnumerable<Child>
. Essa sintaxe de consulta usa oGroupJoin
método sob o capô.Poderíamos fazer
select g
na última consulta, que selecionaria umaIEnumerable<IEnumerable<Child>>
, digamos uma lista de listas. Em muitos casos, a seleção com o pai incluído é mais útil.Alguns casos de uso
1. Produzindo uma junção externa plana.
Como disse, a declaração ...
... produz uma lista de pais com grupos de crianças. Isso pode ser transformado em uma lista simples de pares pai-filho por duas pequenas adições:
O resultado é semelhante ao
Observe que a variável range
c
é reutilizada na instrução acima. Fazendo isso, qualquerjoin
instrução pode simplesmente ser convertida em umaouter join
adicionando o equivalenteinto g from c in g.DefaultIfEmpty()
a umajoin
instrução existente .É aqui que a sintaxe da consulta (ou abrangente) brilha. A sintaxe do método (ou fluente) mostra o que realmente acontece, mas é difícil escrever:
Portanto, um apartamento
outer join
no LINQ é umGroupJoin
, achatado porSelectMany
.2. Preservando a ordem
Suponha que a lista de pais seja um pouco mais longa. Algumas UI produzem uma lista de pais selecionados como
Id
valores em uma ordem fixa. Vamos usar:Agora os pais selecionados devem ser filtrados da lista de pais nesta ordem exata.
Se nós fizermos ...
... a ordem de
parents
determinará o resultado. Se os pais são ordenados porId
, o resultado será os pais 2, 3, 4, 7. Não é bom. No entanto, também podemos usarjoin
para filtrar a lista. E, usandoids
como primeira lista, o pedido será preservado:O resultado são os pais 3, 7, 2, 4.
fonte
De acordo com o eduLINQ :
A única diferença está na declaração de retorno:
Inscreva - se :
Grupo :
Leia mais aqui:
Reimplementando o LINQ to Objects: Parte 19 - Participar
Reimplementando LINQ to Objects: Parte 22 - GroupJoin
fonte