Linq Group Join in C#

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.

Linq Group Join in C# with Examples

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.

  1. Outer Data Source
  2. Inner Data Source
  3. Outer Key Selector
  4. Inner Key Selector
  5. 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.

Group Join using Method Syntax Example in C#

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:

Group Join Method Syntax 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.

Group Join Using Query Syntax

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#.

Leave a Reply

Your email address will not be published. Required fields are marked *