Como executar a junção externa esquerda no C # LINQ para objetos sem usar join-on-equals-into
cláusulas? Existe alguma maneira de fazer isso com a where
cláusula? Problema correto: a junção interna é fácil e eu tenho uma solução como esta
List<JoinPair> innerFinal = (from l in lefts from r in rights where l.Key == r.Key
select new JoinPair { LeftId = l.Id, RightId = r.Id})
mas para a junção externa esquerda, preciso de uma solução. O meu é algo parecido com isto, mas não está funcionando
List< JoinPair> leftFinal = (from l in lefts from r in rights
select new JoinPair {
LeftId = l.Id,
RightId = ((l.Key==r.Key) ? r.Id : 0
})
onde JoinPair é uma classe:
public class JoinPair { long leftId; long rightId; }
Respostas:
Como indicado em:
101 amostras LINQ - junção externa esquerda
fonte
Se um provedor LINQ orientado a banco de dados for usado, uma junção externa esquerda significativamente mais legível pode ser gravada da seguinte forma:
Se você omitir
DefaultIfEmpty()
, terá uma junção interna.Tome a resposta aceita:
Essa sintaxe é muito confusa e não está claro como ela funciona quando você deseja sair da junção de tabelas MÚLTIPLAS.
Nota
Deve-se observar que
from alias in Repo.whatever.Where(condition).DefaultIfEmpty()
é o mesmo que uma aplicação externa / lateral esquerda da junção, que qualquer otimizador de banco de dados (decente) é perfeitamente capaz de converter em uma junção esquerda, desde que você não apresente por linha -valores (também conhecido como uma aplicação externa real). Não faça isso no Linq-2-Objects (porque não há otimizador de banco de dados ao usar o Linq-to-Objects).Exemplo Detalhado
Quando usado com o LINQ 2 SQL, ele será traduzido de maneira adequada para a seguinte consulta SQL legível:
Editar:
Consulte também " Converter consulta do SQL Server em consulta Linq " para obter um exemplo mais complexo.
Além disso, se você estiver fazendo isso no Linq-2-Objects (em vez do Linq-2-SQL), faça da maneira antiga (porque o LINQ to SQL converte isso corretamente para ingressar nas operações, mas sobre os objetos desse método força uma verificação completa e não tira proveito das pesquisas de índice, seja qual for ...):
fonte
join
é muito mais legível e clara do que umawhere
seguida porDefaultIfEmpty
Usando expressão lambda
fonte
Enumerable.Empty<Product>.DefaultIfEmpty()
retornará um IEnumerable com um único valor dedefault(Product)
.Agora como um método de extensão:
Use como você normalmente usaria o join:
Espero que isso poupe algum tempo.
fonte
Dê uma olhada neste exemplo . Esta consulta deve funcionar:
fonte
r
ser acessado na cláusula select após o uso de uma associação?r
a segundafrom
cláusula. iefrom r in lrs.DefaultIfEmpty()
Caso contrário, esta consulta não faz muito sentido e, provavelmente, nem sequer compilar devido ar
estar fora de contexto para a seleção.Clockwise
com John Cleese, lol.Uma implementação de junção externa esquerda por métodos de extensão pode parecer
O seletor de resultados precisa cuidar dos elementos nulos. Fx.
fonte
dê uma olhada neste exemplo
agora você é capaz de,
include elements from the left
mesmo se esse elementohas no matches in the right
, no nosso caso, recuperamosArlene
até ele não ter correspondência no certoaqui está a referência
Como executar junções externas esquerdas (Guia de Programação em C #)
fonte
Esta é a forma geral (como já fornecido em outras respostas)
No entanto, aqui está uma explicação que espero esclarecer o que isso realmente significa!
essencialmente cria um conjunto de resultados separado b_temp que inclui efetivamente 'linhas' nulas para entradas no lado direito (entradas em 'b').
Então a próxima linha:
..itera sobre esse conjunto de resultados, definindo o valor nulo padrão da 'linha' no lado direito e definindo o resultado da junção da linha do lado direito para o valor de 'b_value' (ou seja, o valor à direita lado, se houver um registro correspondente, ou 'null', se não houver).
Agora, se o lado direito for o resultado de uma consulta LINQ separada, ela consistirá em tipos anônimos, que podem ser apenas 'algo' ou 'nulo'. Se, no entanto, for um enumerável (por exemplo, uma Lista - onde MyObjectB é uma classe com 2 campos), é possível ser específico sobre quais valores 'nulos' padrão são usados para suas propriedades:
Isso garante que 'b' em si não seja nulo (mas suas propriedades podem ser nulas, usando os valores nulos padrão que você especificou) e permite verificar as propriedades de b_value sem obter uma exceção de referência nula para b_value. Observe que, para um DateTime anulável, um tipo de (DateTime?), Ou seja, 'DateTime anulável' deve ser especificado como o 'Tipo' do nulo na especificação do 'DefaultIfEmpty' (isso também se aplica a tipos que não são 'nativos'). 'anulável, por exemplo, duplo, flutuante).
Você pode executar várias junções externas esquerdas encadeando a sintaxe acima.
fonte
Aqui está um exemplo se você precisar juntar mais de 2 tabelas:
Ref: https://stackoverflow.com/a/17142392/2343
fonte
Método de extensão que funciona como junção esquerda com sintaxe de junção
acabou de escrever no núcleo do .NET e parece estar funcionando conforme o esperado.
Teste pequeno:
fonte
Aqui está uma versão bastante fácil de entender usando a sintaxe do método:
fonte
Existem três tabelas: pessoas, escolas e people_schools, que conectam pessoas às escolas em que estudam. Uma referência à pessoa com id = 6 está ausente na tabela person_schools. No entanto, a pessoa com id = 6 é apresentada na grade unida à esquerda do resultado.
fonte
Essa é uma sintaxe SQL comparada à sintaxe LINQ para junções externas internas e externas. Junção externa esquerda:
http://www.ozkary.com/2011/07/linq-to-entity-inner-and-left-joins.html
"O exemplo a seguir faz uma junção de grupo entre produto e categoria. Essa é essencialmente a junção esquerda. A expressão into retorna dados mesmo que a tabela de categorias esteja vazia. Para acessar as propriedades da tabela de categorias, agora precisamos selecionar o resultado enumerável adicionando o from cl na instrução catList.DefaultIfEmpty ().
fonte
Executar junções externas esquerdas no linq C # // Executar junções externas esquerdas
https://dotnetwithhamid.blogspot.in/
fonte
Gostaria de acrescentar que, se você receber a extensão MoreLinq, agora há suporte para junções esquerdas homogêneas e heterogêneas agora
http://morelinq.github.io/2.8/ref/api/html/Overload_MoreLinq_MoreEnumerable_LeftJoin.htm
exemplo:
EDITAR:
Em retrospecto, isso pode funcionar, mas converte o IQueryable em um IEnumerable, pois o morelinq não converte a consulta em SQL.
Em vez disso, você pode usar um GroupJoin como descrito aqui: https://stackoverflow.com/a/24273804/4251433
Isso garantirá que ele permaneça como um IQueryable, caso você precise executar mais operações lógicas posteriormente.
fonte
A maneira mais fácil é usar a palavra-chave Let. Isso funciona para mim.
Esta é uma simulação do Left Join. Se cada item na tabela B não corresponder ao item A, BItem retornará nulo
fonte
Se você precisar ingressar e filtrar algo, isso pode ser feito fora da associação. O filtro pode ser feito após a criação da coleção.
Nesse caso, se eu fizer isso na condição de junção, reduzo as linhas retornadas.
A condição ternária é usada
(= n == null ? "__" : n.MonDayNote,)
Se o objeto estiver
null
(portanto, sem correspondência), retorne o que está após o?
.__
, nesse caso.Else, devolver o que é após o
:
,n.MonDayNote
.Graças aos outros colaboradores, foi aí que comecei com meu próprio problema.
fonte
RESULTADO
fonte
De acordo com minha resposta a uma pergunta semelhante, aqui:
Junção externa esquerda de Linq para SQL usando sintaxe Lambda e junção em 2 colunas (chave de junção composta)
Obtenha o código aqui ou clone meu repositório no github e jogue!
Inquerir:
Lambda:
fonte
Visão geral: neste trecho de código, demonstro como agrupar por ID onde a Tabela1 e a Tabela2 têm um relacionamento um para muitos. Eu agrupo em Id, Field1 e Field2. A subconsulta é útil, se uma terceira pesquisa de Tabela for necessária e ela exigiria um relacionamento de associação à esquerda. Eu mostro um agrupamento de junção esquerdo e uma subconsulta linq. Os resultados são equivalentes.
fonte
fonte
Solução simples para a junção externa esquerda :
notas :
fonte
setA
esetB
na resposta.