"Si un trabajador quiere hacer bien su trabajo, primero debe afilar sus herramientas." - Confucio, "Las Analectas de Confucio. Lu Linggong"
Página delantera > Programación > Explicación detallada del método de operación de la conexión externa LINQ

Explicación detallada del método de operación de la conexión externa LINQ

Publicado el 2025-03-13
Navegar:344

How to Perform a Full Outer Join in LINQ?

Linq - conexión externa completa

pregunta:

¿Cómo realizar una conexión completa entre dos listas de objetos basadas en los campos clave comunes, asegurando que todos los registros en ambas listas estén incluidos en el resultado, incluso si no tienen coincidencias correspondientes en la otra lista?

Respuesta:

1.

Para implementar una conexión externa completa en Linq, podemos definir un método de extensión personalizado de la siguiente manera:

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.

En el ejemplo proporcionado, tenemos dos listas:

FirstNames

y lastNames . Para realizar una conexión externa completa, podemos usar el siguiente código:

var outerjoin = desde primero en los primerosnames Únete al último en LastNames en First.id es igual a los últimos.id en temperatura del último en temp.defaultifempty () seleccionar nuevo { id = primero! = nulo? FirstName = First! = NULL? incidente = último! = nulo? };
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 una unión externa izquierda, donde cada registro en

FirstNames

está conectado al primer registro de coincidencia en

LastNames y se conecta al valor predeterminado si no se encuentra ninguna coincidencia. La instrucción en temp crea una colección temporal de registros coincidentes en lastnames , lo que nos permite aplicar defaultiFempty () para garantizar que se incluyan registros de incumplimiento. Esto realmente implementa una conexión externa izquierda, no una conexión externa completa en el sentido completo. Para lograr una conexión externa completa, debe usar el método de extensión Fullouterjoin personalizado anteriormente. 4. La salida esperada para una conexión completamente externa es:

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

ID  FirstName  LastName
--  ---------  --------
1   John       Doe
2   Sue        
3             Smith
para el nombre no coincidente y un entero negativo para la identificación no coincidente.

6.

El tiempo de ejecución de la conexión completamente externa es o (n m), donde n y m son las longitudes de las dos listas de entrada. Esto se debe a que la operación tolookup () toma o (n) tiempo, y las operaciones posteriores requieren tiempo o (n m).

7.

Esta implementación de la conexión completamente externa no es actualmente parte del estándar LINQ, pero se ha recomendado que la incluya en versiones futuras. El LINQ estándar no admite directamente las conexiones externas completas y requiere un método de extensión personalizado para implementarlo.

Último tutorial Más>

Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.

Copyright© 2022 湘ICP备2022001581号-3