Join and GroupJoin help you combine two lists based on matching values. They make it easy to find related data from different sources.
Join and GroupJoin operations in C Sharp (C#)
var joinResult = list1.Join(
list2,
item1 => item1.Key,
item2 => item2.Key,
(item1, item2) => new { item1, item2 }
);
var groupJoinResult = list1.GroupJoin(
list2,
item1 => item1.Key,
item2 => item2.Key,
(item1, group) => new { item1, group }
);Join matches items one-to-one based on keys.
GroupJoin matches one item to many related items as a group.
var joinResult = students.Join(
grades,
student => student.Id,
grade => grade.StudentId,
(student, grade) => new { student.Name, grade.Score }
);var groupJoinResult = students.GroupJoin(
grades,
student => student.Id,
grade => grade.StudentId,
(student, gradesGroup) => new { student.Name, Grades = gradesGroup.Select(g => g.Score) }
);This program shows how to use Join to pair each student with each of their grades, and GroupJoin to group all grades per student.
using System; using System.Collections.Generic; using System.Linq; class Program { public class Student { public int Id { get; set; } public string Name { get; set; } } public class Grade { public int StudentId { get; set; } public int Score { get; set; } } static void Main() { var students = new List<Student> { new() { Id = 1, Name = "Alice" }, new() { Id = 2, Name = "Bob" }, new() { Id = 3, Name = "Charlie" } }; var grades = new List<Grade> { new() { StudentId = 1, Score = 85 }, new() { StudentId = 1, Score = 90 }, new() { StudentId = 2, Score = 78 } }; var joinResult = students.Join( grades, student => student.Id, grade => grade.StudentId, (student, grade) => new { student.Name, grade.Score } ); Console.WriteLine("Join result (student and each grade):"); foreach (var item in joinResult) { Console.WriteLine($"{item.Name} scored {item.Score}"); } var groupJoinResult = students.GroupJoin( grades, student => student.Id, grade => grade.StudentId, (student, gradesGroup) => new { student.Name, Scores = gradesGroup.Select(g => g.Score) } ); Console.WriteLine("\nGroupJoin result (student and all grades):"); foreach (var item in groupJoinResult) { var scores = string.Join(", ", item.Scores); Console.WriteLine($"{item.Name} scored: {scores}"); } } }
If no matching items are found in Join, those items are skipped.
GroupJoin always includes all items from the first list, even if the group is empty.
Use GroupJoin when you want to keep all items from the first list and group related items from the second.
Join matches items one-to-one based on keys.
GroupJoin matches one item to many related items as a group.
Both help combine related data from two lists easily.
Practice
What is the main difference between Join and GroupJoin in C# LINQ?
Solution
Step 1: Understand
JoinbehaviorJoinpairs each item from the first list with exactly one matching item from the second list based on a key.Step 2: Understand
GroupJoinbehaviorGroupJoinpairs each item from the first list with a collection (group) of matching items from the second list.Final Answer:
Joinmatches one item to one item;GroupJoinmatches one item to many items as a group. -> Option AQuick Check:
Join = one-to-one, GroupJoin = one-to-many [OK]
- Thinking Join creates groups
- Confusing GroupJoin with Join syntax
- Assuming Join works only with arrays
Which of the following is the correct syntax to perform a Join operation in C# LINQ?
var result = from a in listA
join b in listB on a.Id equals b.Id
select new { a.Name, b.Value };Solution
Step 1: Check correct
The correct syntax usesjoinsyntaxjoin b in listB on a.Id equals b.Idto specify the matching keys.Step 2: Identify errors in other options
var result = from a in listA join b in listB where a.Id == b.Id select new { a.Name, b.Value }; useswhereinstead ofon ... equals, which is invalid forjoin. var result = from a in listA join b in listB by a.Id equals b.Id select new { a.Name, b.Value }; misplacesby. var result = from a in listA join b in listB on a.Id == b.Id select new { a.Name, b.Value }; uses==instead ofequals.Final Answer:
var result = from a in listA join b in listB on a.Id equals b.Id select new { a.Name, b.Value }; -> Option CQuick Check:
Join syntax = on ... equals ... [OK]
- Using '==' instead of 'equals' in join
- Replacing 'on' with 'where' in join
- Adding extra keywords like 'by'
What is the output of the following C# code?
var students = new[] {
new { Id = 1, Name = "Alice" },
new { Id = 2, Name = "Bob" }
};
var scores = new[] {
new { StudentId = 1, Score = 90 },
new { StudentId = 1, Score = 85 },
new { StudentId = 2, Score = 88 }
};
var query = students.GroupJoin(scores,
s => s.Id,
sc => sc.StudentId,
(s, scGroup) => new {
Student = s.Name,
Scores = scGroup.Select(x => x.Score).ToList()
});
foreach (var item in query) {
Console.WriteLine($"{item.Student}: {string.Join(",", item.Scores)}");
}Solution
Step 1: Understand GroupJoin matching
Each student is matched with all scores whereStudentIdequalsId. Alice (Id=1) matches scores 90 and 85; Bob (Id=2) matches score 88.Step 2: Output formatting
The code prints each student's name followed by their scores joined by commas. So output lines are "Alice: 90,85" and "Bob: 88".Final Answer:
Alice: 90,85 Bob: 88 -> Option BQuick Check:
GroupJoin groups scores by student [OK]
- Assuming Join returns groups
- Mixing up StudentId and Id keys
- Printing scores incorrectly
Identify the error in this C# LINQ GroupJoin code snippet:
var result = listA.GroupJoin(listB,
a => a.Id,
b => b.Id,
(a, bGroup) => new {
a.Name,
bGroup
});Solution
Step 1: Check usage of
bGroupin projectionbGroupis anIEnumerableof matching items. It cannot be used directly in the anonymous type without materializing it (e.g.,bGroup.ToList()) because it is lazily evaluated and multiple enumerations can lead to unexpected behavior or performance issues.Step 2: Rule out other options
Noselectkeyword is needed--the lambda is the projection. Lambda parametersaandbcan have different names.GroupJoinrequires only two collections.Final Answer:
Cannot usebGroupdirectly without projection likeToList(). -> Option AQuick Check:
GroupJoin returns groups; project with ToList() for clarity [OK]
- Thinking GroupJoin needs select keyword
- Assuming lambda parameter names must match
- Expecting extra collection parameter
You have two lists: authors and books. Each book has an AuthorId. You want to create a list showing each author and all their book titles, but if an author has no books, show an empty list. Which LINQ operation is best?
Solution
Step 1: Understand requirement for grouping
You want each author with a collection of their books, including authors with no books (empty list).Step 2: Choose correct LINQ operation
GroupJoincreates a one-to-many relationship and includes authors with no matching books, producing empty groups as needed.Final Answer:
UseGroupJointo group books by author. -> Option DQuick Check:
GroupJoin = one-to-many with empty groups included [OK]
- Using Join excludes authors without books
- Filtering authors removes those without books
- SelectMany flattens, losing grouping
Ready to prove it?
Pass the test and this pattern moves unknown
