左外部結合の実行
左外部結合は、最初のコレクションの各要素を、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: