Maison >développement back-end >C++ >Comment effectuer une jointure extérieure complète dans Linq?

Comment effectuer une jointure extérieure complète dans Linq?

Patricia Arquette
Patricia Arquetteoriginal
2025-01-31 17:21:13803parcourir

How to Perform a Full Outer Join in LINQ?

Linq -Unter Connexion extérieure

Question:

Comment effectuer une connexion complète entre les deux objets en fonction du champ de clé publique pour s'assurer que tous les enregistrements des deux listes sont inclus dans les résultats.

Réponse:

1. Méthode d'extension personnalisée connectée à l'ensemble à l'extérieur

Afin d'obtenir une connexion extérieure dans LINQ, nous pouvons définir une méthode d'extension personnalisée, comme indiqué ci-dessous:

2. Implémentez

Dans l'exemple fourni, nous avons deux listes:
<code class="language-csharp">public static IEnumerable<TResult> FullOuterJoin<TA, TB, TKey, TResult>(
    this IEnumerable<TA> a,
    IEnumerable<TB> b,
    Func<TA, TKey> selectKeyA,
    Func<TB, TKey> selectKeyB,
    Func<TA, TB, TKey, TResult> projection,
    TA defaultA = default(TA),
    TB defaultB = default(TB),
    IEqualityComparer<TKey> cmp = null)
{
    cmp = cmp ?? EqualityComparer<TKey>.Default;
    var alookup = a.ToLookup(selectKeyA, cmp);
    var blookup = b.ToLookup(selectKeyB, cmp);

    var keys = new HashSet<TKey>(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;
}</code>
et

. Pour exécuter la connexion extérieure, nous pouvons utiliser le code suivant:

firstNames 3. Explication lastNames Ce code utilise une connexion extérieure gauche, et chaque enregistrement dans

est connecté au premier enregistrement de match dans
<code class="language-csharp">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
                };</code>
.

L'énoncé crée une collection temporaire de

enregistrements correspondants, nous permettant d'appliquer

pour garantir qu'il contient des enregistrements sans satiss. Cela réalise en fait la connexion externe gauche, pas une connexion complète dans le sens complet. Pour obtenir une connexion extérieure, vous devez utiliser la méthode d'expansion personnalisée ci-dessus. firstNames lastNames 4. attendre la sortie into temp lastNames La sortie attendue de la connexion externe est: DefaultIfEmpty() FullOuterJoin

5. La valeur par défaut définie

La méthode d'extension vous permet de spécifier la valeur par défaut pour les enregistrements insatisfaisants. Dans l'exemple, nous spécifions

pour le nom insatisfaisant, et nous spécifions l'entier négatif pour l'ID non-correspondant.

<code>ID  FirstName  LastName
--  ---------  --------
1   John       Doe
2   Sue        
3             Smith</code>
6. Précautions de performance

Le temps d'exécution de la connexion extérieure entière est O (n m), où n et m sont la longueur des deux listes d'entrée. En effet, l'opération

nécessite du temps O (n), et les opérations suivantes nécessitent du temps O (n m). string.Empty

7. Implémentation LINQ

Cette implémentation de l'ensemble de la connexion extérieure ne fait actuellement pas partie de la norme LINQ, mais elle est recommandée de l'inclure dans la future version. Linq standard ne prend pas directement en charge la connexion extérieure et doit être personnalisée pour y parvenir.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn