"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > Explicação detalhada do método de operação da conexão externa completa do LINQ

Explicação detalhada do método de operação da conexão externa completa do LINQ

Postado em 2025-03-13
Navegar:981

How to Perform a Full Outer Join in LINQ?

linq - conexão externa completa

pergunta:

Como executar uma conexão completa entre duas listas de objetos com base nos campos -chave comuns, garantindo que todos os registros nas duas listas estejam incluídos no resultado, mesmo que não tenham correspondências correspondentes na outra lista?

Responder:

1.

Para implementar a conexão externa completa no LINQ, podemos definir um método de extensão personalizado da seguinte maneira:

public static IEnumerable FullOuterJoin(
    this IEnumerable a,
    IEnumerable b,
    Func selectKeyA,
    Func selectKeyB,
    Func projection,
    TA defaultA = default(TA),
    TB defaultB = default(TB),
    IEqualityComparer cmp = null)
{
    cmp = cmp ?? EqualityComparer.Default;
    var alookup = a.ToLookup(selectKeyA, cmp);
    var blookup = b.ToLookup(selectKeyB, cmp);

    var keys = new HashSet(alookup.Select(p => p.Key), cmp);
    keys.UnionWith(blookup.Select(p => p.Key));

    var join = from key in keys
               from xa in alookup[key].DefaultIfEmpty(defaultA)
               from xb in blookup[key].DefaultIfEmpty(defaultB)
               select projection(xa, xb, key);

    return join;
}
2.

No exemplo fornecido, temos duas listas:

FirstNames

e lastNames . Para executar uma conexão externa completa, podemos usar o seguinte código:

var outerJoin = do primeiro nos nomes do primeiro Junte -se a Last em LastNames em primeiro.id é igual a último.id em temp De Last in Temp.DefaultIfempty () selecione novo { id = primeiro! = nulo? FirstName = primeiro! = NULL? Incidente = Last! = NULL? };
var outerJoin = from first in firstNames
                join last in lastNames
                on first.ID equals last.ID
                into temp
                from last in temp.DefaultIfEmpty()
                select new
                {
                    id = first != null ? first.ID : last.ID,
                    firstname = first != null ? first.Name : string.Empty,
                    surname = last != null ? last.Name : string.Empty
                };
Este código usa uma junção externa esquerda, onde cada registro em

FirstNames

está conectado ao primeiro registro correspondente em

lastNames e se conecta ao valor padrão se nenhuma correspondência for encontrada. A instrução na Temp cria uma coleção temporária de registros correspondentes em lastNames , permitindo que aplique defaultifempty () para garantir que os registros de incompatibilidade sejam incluídos. Na verdade, isso implementa uma conexão externa esquerda, não uma conexão externa completa no sentido completo. Para obter uma conexão externa completa, você precisa usar o método de extensão fullouterJoin personalizado acima. 4. A saída esperada para uma conexão totalmente externa é:

ID FirstName LastName -------------------- 1 John Doe 2 Sue 3 Smith

ID  FirstName  LastName
--  ---------  --------
1   John       Doe
2   Sue        
3             Smith
para o nome incompatível e um número inteiro negativo para o ID incompatível.

6.

O tempo de execução da conexão totalmente externa é o (n m), onde n e m são os comprimentos das duas listas de entrada. Isso ocorre porque a operação tolookup () leva o tempo o (n) e as operações subsequentes requerem o tempo o (n m).

7.

Esta implementação de conexão totalmente externa não faz parte do padrão LINQ, mas foi recomendável incluí -la em versões futuras. O Standard LinQ não suporta conexões externas completas diretamente e requer um método de extensão personalizado para implementá -lo.

Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3