Updated on 08 Oct 2025 by Admin

Inner Join in LINQ

In SQL Server, when we perform an INNER join, only the matching elements from the 2 tables are included in the result set, and non-matching elements are simply excluded, as shown in the following diagram:

Inner Join in Sql Server
Inner Join in SQL Server

But, with LINQ, we don't query a database table directly; rather, we query the collection of objects. The Entity Framework converts the tables into a collection of objects, and we simply query those collections (DbSets), and then the LINQ provider translates our query to corresponding T-SQL.

How to think
How to think when working with LINQ

The Entity Framework will generate the following domain model based on the Employee and Department tables mentioned above:

Entity Model generated by EF
Entity Model generated by EF

In LINQ, we have the Join operator to perform the Inner Join. If we have 2 collections, and we perform an Inner Join, then only the matching elements from the 2 collections are included in the result set. Non-matching elements are excluded.

Join in Method Syntax

Entity Model generated by EF
Entity Model generated by EF
public static void Main()
{
OrganizationContext db = new OrganizationContext();
var result= db.Departments.Join(db.Employees, x => x.Id, x => x.DepartmentId, (d, e) => new
{
departmentName = d.Name,
EmployeeName = e.Name,
Salary = e.Salary
});
foreach (var item in result)
{
Console.WriteLine("{0}|{1}|{2}",item.departmentName,item.EmployeeName,item.Salary);
}
Console.ReadLine();
 }

Like all other LINQ operators, Join is an extension method on IQueryalbe<T>, which means we can apply the Join operator to any Collection type. In the above example of a join query,

  • Department collection is an outer sequence because the query starts from it.
  • The first parameter in the Join method is used to specify the inner sequence, which is Departments in the above example.
  • The second and third parameters of the Join method are used to specify a field whose value should be matched using a lambda expression to include an element in the result. The key selector for the outer sequence x =>x.Id indicates that the Id field of each element of Department should be matched with the key of the inner sequence x=>x.DepartmentId. If the value of both the key fields is matched, then include that element in the result.
  • The last parameter in the Join method is an expression to formulate the result. In the above example, the result selector includes the Department's Name, Employee's Name, and Employee's Salary property of both sequences.

Output: Notice that, in the output, we don't have any record of Department's Id 3 (BA Department). This is because the BA department does not have a matching employee in the Employee collection. In other words, there is no employee in the BA department, so the BA department has been excluded from the result. So this is effectively an Inner Join.

Join in Query Syntax

The Join operator in query syntax works a little differently than the method syntax. It requires four parameters, namely the outer sequence, inner sequence, key selector, and result selector. The 'on' keyword is used for a key selector where the left side of the 'equals' operator becomes the outerKeySelector and the right side of 'equals' becomes the innerKeySelector.

Example: Convert the First Example to Sql-Like Syntax

public static void Main()
{
OrganizationContext db = new OrganizationContext();
var result = from d in db.Departments
join e in db.Employees
on d.Id equals e.DepartmentId
select new
{
departmentName = d.Name,
EmployeeName = e.Name,
Salary = e.Salary
};
foreach (var item in result)
{
Console.WriteLine("{0}|{1}|{2}",item.departmentName,item.EmployeeName,item.Salary);
}
Console.ReadLine();
}


You need to login to post a comment.

Sharpen Your Skills with These Next Guides