Back to: LINQ Tutorial For Beginners and Professionals
Linq Group Join in C# using both Method and Query Syntax
In this article, I am going to discuss Linq Group Join in C# using both Method and Query Syntax. Please read our previous article before proceeding to this article where we discussed how to join multiple data sources in LINQ with some examples.
What is Linq Group Join?
In Linq, we can apply the Group Join on two or more data sources based on a common key (the key must exist in both the data sources) and then it produces the result set in the form of groups. In simple words, we can say that Linq Group Join is used to group the result sets based on a common key.
So, the Group Join is basically used to produces hierarchical data structures. Each item from the first data source is paired with a set of correlated items from the second data source. There are two overloaded versions of this method is available as shown below.
The difference between these two methods is that the second overloaded versions take an additional IEqualityComparer. So, when working with Group Join we need to understand the following things.
- Outer Data Source
- Inner Data Source
- Outer Key Selector
- Inner Key Selector
- Result Selector
Creating Models and Data Sources:
Let us understand Linq Group Join with an example. We are going to use the following Employee and Department data sources in this demo. Please create a class file and then copy and paste the following code in it.
using System.Collections.Generic; namespace LINQJoin { public class Employee { public int ID { get; set; } public string Name { get; set; } public int DepartmentId { get; set; } public static List<Employee> GetAllEmployees() { return new List<Employee>() { new Employee { ID = 1, Name = "Preety", DepartmentId = 10}, new Employee { ID = 2, Name = "Priyanka", DepartmentId =20}, new Employee { ID = 3, Name = "Anurag", DepartmentId = 30}, new Employee { ID = 4, Name = "Pranaya", DepartmentId = 30}, new Employee { ID = 5, Name = "Hina", DepartmentId = 20}, new Employee { ID = 6, Name = "Sambit", DepartmentId = 10}, new Employee { ID = 7, Name = "Happy", DepartmentId = 10}, new Employee { ID = 8, Name = "Tarun", DepartmentId = 0}, new Employee { ID = 9, Name = "Santosh", DepartmentId = 10}, new Employee { ID = 10, Name = "Raja", DepartmentId = 20}, new Employee { ID = 11, Name = "Ramesh", DepartmentId = 30} }; } } public class Department { public int ID { get; set; } public string Name { get; set; } public static List<Department> GetAllDepartments() { return new List<Department>() { new Department { ID = 10, Name = "IT"}, new Department { ID = 20, Name = "HR"}, new Department { ID = 30, Name = "Sales" }, }; } } }
As you can see we created the above Employee and Department classes with some simple properties. The common property is Department ID i.e. the ID property in Department class and DepartmentID property in Employee class. Then we create two simple methods that are going to return the respective data sources. Further, if you notice the employee with ID 8 does not have a department.
Example1: Using Method Syntax
Here we need to group the employees by department. So, the outer data source is going to be the department data source and the inner data source is going to be the employee data source. Please have a look at the following image.
The complete example is given below.
using System.Linq; using System; namespace LINQJoin { class Program { static void Main(string[] args) { //Group Join using Method Syntax var GroupJoinMS = Department.GetAllDepartments(). GroupJoin( Employee.GetAllEmployees(), dept => dept.ID, emp => emp.DepartmentId, (dept, emp) => new {dept, emp} ); //Printing the Result set //Outer Foreach is for all department foreach(var item in GroupJoinMS) { Console.WriteLine("Department :" + item.dept.Name); //Inner Foreach loop for each employee of a department foreach(var employee in item.emp) { Console.WriteLine(" EmployeeID : " + employee.ID + " , Name : " + employee.Name); } } Console.ReadLine(); } } }
Output:
As you can see the employee with id 8 does not display here. This is because the employee with id 8 does not belong to any department.
Example2: Using Query Syntax
In query syntax there is no such Group Join operator is available. Here we need to use inner join along with the “into” operator. Let’s have a look at the following image.
The complete code is given below.
using System.Linq; using System; namespace LINQJoin { class Program { static void Main(string[] args) { var GroupJoinQS = from dept in Department.GetAllDepartments() join emp in Employee.GetAllEmployees() on dept.ID equals emp.DepartmentId into EmployeeGroups select new { dept, EmployeeGroups }; //Outer Foreach is for all department foreach(var item in GroupJoinQS) { Console.WriteLine("Department :" + item.dept.Name); //Inner Foreach loop for each employee of a department foreach(var employee in item.EmployeeGroups) { Console.WriteLine(" EmployeeID : " + employee.ID + " , Name : " + employee.Name); } } Console.ReadLine(); } } }
It will print the same output as the previous example.
Example3: Specifying user-defined names in ResultSet
It is also possible to specify user-defined names as shown in the below example.
using System.Linq; using System; namespace LINQJoin { class Program { static void Main(string[] args) { //Using Method Syntax var GroupJoinMS = Department.GetAllDepartments(). GroupJoin( Employee.GetAllEmployees(), dept => dept.ID, emp => emp.DepartmentId, //User Defined names in Result Selector (dept, emp) => new{ Departments = dept, Employees = emp } ); //Using Query Syntax var GroupJoinQS = from dept in Department.GetAllDepartments() join emp in Employee.GetAllEmployees() on dept.ID equals emp.DepartmentId into EmployeeGroups //User Defined names in Result Selector select new { Departments = dept, Employees = EmployeeGroups }; foreach(var item in GroupJoinQS) { Console.WriteLine("Department :" + item.Departments.Name); foreach(var employee in item.Employees) { Console.WriteLine(" EmployeeID : " + employee.ID + " , Name : " + employee.Name); } } Console.ReadLine(); } } }
In the next article, I am going to discuss the Left Outer Join in Linq with some examples. In this article, I try to explain the Linq Group Join using both Method and Query Syntax example in C#.