左外部結合の実行

左外部結合は、最初のコレクションの各要素を、2 つ目のコレクション内にある要素との相関関係の有無にかかわらず返す結合です。 LINQ を使用すると、グループ結合の結果に対して DefaultIfEmpty メソッドを呼び出すことで、左外部結合を実行できます。

注意

このトピックの例では、「内部結合の実行」からの Pet および Person データ クラスを使用します。

次の例は、グループ結合の結果に対して DefaultIfEmpty メソッドを使用し、左外部結合を実行する方法を示しています。

2 つのコレクションの左外部結合を作成するための最初のステップは、グループ結合を使用して内部結合を実行することです。 (このプロセスの説明については、「内部結合の実行」を参照してください)。この例では、Person オブジェクトのリストは、Pet.Owner に一致する Person オブジェクトに基づいて Pet オブジェクトのリストに内部結合されます。

2 つ目のステップは、最初 (左側) のコレクションの各要素を結果セットに含めることです。このとき、その要素と一致するものが右のコレクションにあるかどうかは考慮しません。 これを行うには、グループ結合内の一致する要素の各シーケンスに対して、DefaultIfEmpty を呼び出します。 この例では、Pet オブジェクトに一致する各シーケンスに対して、DefaultIfEmpty が呼び出されています。 このメソッドは、Person オブジェクトに対して一致する Pet オブジェクトのシーケンスが空である場合に、単一の既定値を含んだコレクションを返します。これにより、各 Person オブジェクトが結果コレクション内に表されることが保証されます。

注意

参照型の既定値は null です。そのためこのコード例では、各 Pet コレクションの各要素にアクセスする前に Null 参照がチェックされます。

Person magnus = new("Magnus", "Hedlund");
Person terry = new("Terry", "Adams");
Person charlotte = new("Charlotte", "Weiss");
Person arlene = new("Arlene", "Huff");

Pet barley = new("Barley", terry);
Pet boots = new("Boots", terry);
Pet whiskers = new("Whiskers", charlotte);
Pet bluemoon = new("Blue Moon", terry);
Pet daisy = new("Daisy", magnus);

// Create two lists.
List<Person> people = new() { magnus, terry, charlotte, arlene };
List<Pet> pets = new() { barley, boots, whiskers, bluemoon, daisy };

var query =
    from person in people
    join pet in pets on person equals pet.Owner into gj
    from subpet in gj.DefaultIfEmpty()
    select new
    {
        person.FirstName,
        PetName = subpet?.Name ?? string.Empty
    };

foreach (var v in query)
{
    Console.WriteLine($"{v.FirstName + ":",-15}{v.PetName}");
}

record class Person(string FirstName, string LastName);
record class Pet(string Name, Person Owner);

// This code produces the following output:
//
// Magnus:        Daisy
// Terry:         Barley
// Terry:         Boots
// Terry:         Blue Moon
// Charlotte:     Whiskers
// Arlene:

関連項目