左外部結合の実行Perform left outer joins

左外部結合は、最初のコレクションの各要素を、2 つ目のコレクション内にある要素との相関関係の有無にかかわらず返す結合です。A left outer join is a join in which each element of the first collection is returned, regardless of whether it has any correlated elements in the second collection. LINQ を使用すると、グループ結合の結果に対して DefaultIfEmpty メソッドを呼び出すことで、左外部結合を実行できます。You can use LINQ to perform a left outer join by calling the DefaultIfEmpty method on the results of a group join.

Example

次の例は、グループ結合の結果に対して DefaultIfEmpty メソッドを使用し、左外部結合を実行する方法を示しています。The following example demonstrates how to use the DefaultIfEmpty method on the results of a group join to perform a left outer join.

2 つのコレクションの左外部結合を作成するための最初のステップは、グループ結合を使用して内部結合を実行することです。The first step in producing a left outer join of two collections is to perform an inner join by using a group join. (このプロセスの詳細については、「内部結合の実行」参照してください。)この例では、Pet.Owner に一致する Person オブジェクトに基づいて、Person オブジェクトの一覧が Pet オブジェクトの一覧に内部結合されています。(See Perform inner joins for an explanation of this process.) In this example, the list of Person objects is inner-joined to the list of Pet objects based on a Person object that matches Pet.Owner.

2 つ目のステップは、最初 (左側) のコレクションの各要素を結果セットに含めることです。このとき、その要素と一致するものが右のコレクションにあるかどうかは考慮しません。The second step is to include each element of the first (left) collection in the result set even if that element has no matches in the right collection. これを行うには、グループ結合内の一致する要素の各シーケンスに対して、DefaultIfEmpty を呼び出します。This is accomplished by calling DefaultIfEmpty on each sequence of matching elements from the group join. この例では、Pet オブジェクトに一致する各シーケンスに対して、DefaultIfEmpty が呼び出されています。In this example, DefaultIfEmpty is called on each sequence of matching Pet objects. このメソッドは、Person オブジェクトに対して一致する Pet オブジェクトのシーケンスが空である場合に、単一の既定値を含んだコレクションを返します。これにより、各 Person オブジェクトが結果コレクション内に表されることが保証されます。The method returns a collection that contains a single, default value if the sequence of matching Pet objects is empty for any Person object, thereby ensuring that each Person object is represented in the result collection.

注意

参照型の既定値は null です。そのためこのコード例では、各 Pet コレクションの各要素にアクセスする前に Null 参照がチェックされます。The default value for a reference type is null; therefore, the example checks for a null reference before accessing each element of each Pet collection.

class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

class Pet
{
    public string Name { get; set; }
    public Person Owner { get; set; }
}

public static void LeftOuterJoinExample()
{
    Person magnus = new Person { FirstName = "Magnus", LastName = "Hedlund" };
    Person terry = new Person { FirstName = "Terry", LastName = "Adams" };
    Person charlotte = new Person { FirstName = "Charlotte", LastName = "Weiss" };
    Person arlene = new Person { FirstName = "Arlene", LastName = "Huff" };

    Pet barley = new Pet { Name = "Barley", Owner = terry };
    Pet boots = new Pet { Name = "Boots", Owner = terry };
    Pet whiskers = new Pet { Name = "Whiskers", Owner = charlotte };
    Pet bluemoon = new Pet { Name = "Blue Moon", Owner = terry };
    Pet daisy = new Pet { Name = "Daisy", Owner = magnus };

    // Create two lists.
    List<Person> people = new List<Person> { magnus, terry, charlotte, arlene };
    List<Pet> pets = new List<Pet> { 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}");
    }
}

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

関連項目See also