CodeBlanks Logo Icon CodeBlanks

GroupJoin

C# course · Advanced · Lesson 27/83

Learn one-to-many joins with GroupJoin.

Hierarchy with GroupJoin

GroupJoin is the grouping cousin of Join. It pairs each outer item with the sequence of matching inner items; even outer items without a match stay in the result. This is ideal for one-to-many relations.

Example: categories.GroupJoin(products, c => c.Id, p => p.CategoryId, (c, prods) => ...). Each category arrives with its product sequence; a category with no products gets an empty sequence, not dropped.

When to use GroupJoin

GroupJoin suits listing all products of a category, all students of a class, or all orders of a customer. When you do not want unmatched outer items dropped, choose it over Join.

The result selector receives the inner sequence as IEnumerable<T>; you can call prods.Count() or iterate with foreach. It resembles a SQL left outer join.

Exercise Group categories with products

GroupJoin the categories and products lists below on Id/CategoryId. For each category print the category name and product count with Console.WriteLine.

Show example solution
" + prods.Count()); then iterate with foreach.
Example solution:
using System;
using System.Collections.Generic;
using System.Linq;

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

class Product
{
    public string Name { get; set; }
    public int CategoryId { get; set; }
}

class Program
{
    static void Main()
    {
        var categories = new List<Category>
        {
            new Category { Id = 1, Name = "Drink" },
            new Category { Id = 2, Name = "Dessert" }
        };
        var products = new List<Product>
        {
            new Product { Name = "Tea", CategoryId = 1 },
            new Product { Name = "Coffee", CategoryId = 1 },
            new Product { Name = "Kunefe", CategoryId = 2 }
        };
        var result = categories.GroupJoin(products, c => c.Id, p => p.CategoryId, (c, prods) => c.Name + ": " + prods.Count());
        foreach (var r in result)
        {
            Console.WriteLine(r);
        }
    }
}

Test yourself

  1. Match the method to its behavior

    Join
    Only matching pairs
    GroupJoin
    Outer + inner seq
    GroupBy
    Group one sequence
    Zip
    Index-based pair
  2. Complete the GroupJoin call

    var result = categories.Group____(products, c => c.Id, p => p.CategoryId, (c, prods) => c.Name);
    Show answer
    var result = categories.GroupJoin(products, c => c.Id, p => p.CategoryId, (c, prods) => c.Name);
  3. What does GroupJoin produce?

    • Only matching pairs
    • A single value
    • Outer item + inner sequence
    • A sorted sequence
    Show answer

    Outer item + inner sequence — Correct. GroupJoin pairs each outer item with its matching inner sequence.

All lessons in Advanced