C# Foundations·C# from first file to first API

LINQ in depth

LINQ builds lazy pipelines that flatten, group and join collections.

Beginner 14 min read Lesson 4 of 300 Challenge included
What you will be able to do
  • Remember queries are lazy until enumerated.
  • Use SelectMany to flatten nested data.
  • Use GroupBy and Join to reshape related data.
  • Materialise with ToList only when you need a concrete snapshot.

In plain English

LINQ, or Language Integrated Query, builds pipelines that filter, project and group collections. Deferred execution means a query runs only when you enumerate it, not when you write it. SelectMany flattens nested collections into one, GroupBy collects items sharing a key, and Join combines two sequences on a matching key. Call ToList or ToArray when you need to materialise the results and reuse them.

Step by step

  1. 1Build a query and observe nothing runs until enumeration.
  2. 2Flatten nested sequences with SelectMany.
  3. 3Group lessons by course with GroupBy.
  4. 4Combine courses and lessons with Join.
  5. 5Materialise with ToList when the result must be reused.
Linq.csC#
record Course(int Id, string Name);
record Lesson(int CourseId, string Title, int Minutes);

var courses = new[]
{
    new Course(1, "C#"),
    new Course(2, "C"),
};

var lessons = new[]
{
    new Lesson(1, "Variables", 12),
    new Lesson(1, "Methods", 11),
    new Lesson(2, "Pointers", 15),
    new Lesson(2, "Structs", 14),
};

var query = lessons.Where(lesson => lesson.Minutes > 11);

var flat = courses
    .SelectMany(course => lessons.Where(lesson => lesson.CourseId == course.Id))
    .ToList();

var grouped = lessons
    .GroupBy(lesson => lesson.CourseId)
    .Select(group => new { CourseId = group.Key, Count = group.Count() })
    .ToList();

var joined = courses
    .Join(lessons,
        course => course.Id,
        lesson => lesson.CourseId,
        (course, lesson) => course.Name + ": " + lesson.Title)
    .ToList();

var materialised = query.ToList();

Common mistakes

  • Re-enumerating a query re-runs it against the current source data.
  • Capturing a loop variable in a query can close over a value you did not expect.
  • Materialising too early duplicates work and memory you may not need.
  • Mixing side effects into a query makes its behaviour depend on when it runs.
Your turn

Group lessons by course

Medium

Given a list of lessons with a CourseId, group them with GroupBy and return the count per course.

CSHARP · starter
var result = lessons;
Check your understanding before moving on.
Knowledge checkQuestion 1

What does SelectMany do?

Select an answer to continue
Study tools

Make it yours.

Keep a private note for this lesson, then turn the key ideas into flashcards you can revisit.

Sign in to save notes and flashcards.Both are private to your account and stay with your progress.
Sign in
Finished reading?

Lock in what you just learned.

Mark this lesson complete to save your place and move one step closer to the certificate.

Next: Testing with xUnit
Lesson 4 of 300 · 0% of course