.NET 10 : Les nouveaux opérateurs LeftJoin et RightJoin
Publié le 12/02/2025
Par  Christophe MOMMER

Comme à chaque nouvelle version de .NET, les auteurs du framework nous gratifient de nouveaux opérateurs visant à, d'une part, nous simplifier la vie, et d'autre part, nous apporter encore plus de possibilité, notamment dans l'usage de LINQ pour la correspondance SQL avec Entity Framework Core.

Nous avions déjà l'opérateur Join, qui permettait de faire une jointure entre des collections d'objets différents sur la base d'un critère commun, et d'obtenir une projection de résultat qui reprenait uniquement les éléments respectant la condition de la jointure (équivalent d'un INNER JOIN en SQL). Si jamais vous avez envie d'en apprendre plus sur ce sujet, j'ai un cours complet dédié aux opérateurs LINQ et cet opérateur est étudié à l'intérieur en détails.

Il restait des cas non couverts, notamment lorsqu'il s'agissait de récupérer, comme en SQL, l'intégralité des objets dans la collection "de gauche ou de droite".

Prenons un exemple simple :

class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}

class Address
{
    public int PersonId { get; set; }
    public string City { get; set; }
}

List<Person> people =
[
    new Person { Id = 1, Name = "Alice" },
    new Person { Id = 2, Name = "Bob" },
    new Person { Id = 3, Name = "Charlie" }
];

List<Address> addresses =
[
    new Address { PersonId = 1, City = "Paris" },
    new Address { PersonId = 2, City = "Lyon" },
    new Address { PersonId = 4, City = "Bordeaux" }
];

Dans cet extrait de code, on voit clairement que chaque personne ne dispose pas forcément d'une adresse. Donc, si on devait faire un Join sur ces deux collections, la personne Charlie ne serait pas dans le résultat. Inversement, la personne d'id 4 n'a visiblement pas été chargée, ainsi l'adresse lui appartenant ne sera pas restituée. Avec les nouveaux opérateurs, on peut dorénavant choisir de les recupérer malgré tout.

Par exemple, si je veux récupérer toutes les personnes, et pour celles qui n'ont pas d'adresses, écrire "Adresse inconnue", je dois faire une jointure sur l'id des personnes en considérant la collection des personnes comme étant la table principale. Donc avec une jointure gauche :

var leftJoinResult = people.LeftJoin(
    addresses,
    person => person.Id,
    address => address.PersonId,
    (person, addressGroup) => new
    {
        person.Name,
        City = addressGroup?.City ?? "Adresse inconnue"
    });

foreach (var item in leftJoinResult)
{
    Console.WriteLine($"{item.Name} habite à {item.City}");
}

Bien évidemment, cela fonctionne aussi pour le RightJoin, sauf que cette fois, c'est la collection passée en paramètre qui sera considérée comme étant la principale. Et bien entendu, vu que nous sommes au tout début des previews, il y a de fortes chances que ces nouveaux opérateurs soient supportés par EF Core pour les opérations SQL du même nom.

Un ajout bienvenu dans le framework !