C# LINQ Joins With Query Structure

LINQ uses an SQL-like syntax to make query expressions well beyond the capabilities of embedded SQL, as implemented in programming languages.

Idea behind LINQ

LINQ (Language Integrated Query) was introduced in .NET Framework 3.5. Suppose, we are working on SQL Server database and we know SQL Server syntax and SQL related ADO.NET object. Now, suppose after some time, the project requirement needs us to switch to another database like Oracle. Now, we need to learn the syntax of Oracle database and Oracle related ADO.NET objects to work with C#.
 
This problem arises with number of technologies. Learning all languages is neither feasible nor possible. So, basically to avoid this, Microsoft introduced LINQ for querying any database MySQL, SQL, Oracle, etc.

Now, in this article, I would like to share how joins work in LINQ with syntax expression comparison with SQL syntax expression.

Kinds of joins in Linq

  1. INNER JOIN
  2. LEFT OUTER JOIN
  3. CROSS JOIN
  4. GROUP JOIN

We have the following three tables (Customer, Product and Order), and the data in these three tables is shown in figure.

INNER JOIN

Inner join returns only those records or rows that match or exists in both the tables.

Suppose we want to use inner join in Customer and Product table.

  1. var q = (from cust in dataContext.tblCustomer join product in dataContext.tblProduct on cust.CustomerId equals product.CustomerId orderby cust.CustomerId select new {  
  2.     cust.CustomerId,  
  3.         cust.Name,  
  4.         product.ProductName,  
  5.         product.Price,  
  6. }).ToList();  

NOTE

dataContext, I used in the previous post

INNER JOIN among more than two tables.

We can apply join on multiple table on condition base.

  1. var q = (from product in dataContext.Products join order in dataContext.Orders on product.ProductId equals order.ProductId join cust in dataContext.Customers on order.CustomerId equals cust.CustomerId orderby order.OrderId select new {  
  2.     order.OrderId,  
  3.         product.ProductId,  
  4.         product.ProductName,  
  5.         product.Price,  
  6.         order.Quantity,  
  7.         Customer = cust.Name  
  8. }).ToList();  

INNER JOIN With Multiple Conditions

Sometimes, we required to apply join with multiple coditions. So in this case, we need to make two anonymous types (one for left table and one for right table) by using new keyword then we compare both the anonymous types. You can see custid,pid below

  1. var q = (from product in dataContext.Products join order in dataContext.Orders on product.ProductId equals order.ProductId join cust in dataContext.Customers on new {  
  2.         custid = order.CustomerId, pid = order.ProductId  
  3.     }  
  4.     equals new {  
  5.         custid = cust.CustomerId, pid = cust.ProductId  
  6.     }  
  7.     orderby order.OrderId select new {  
  8.         order.OrderId,  
  9.             product.ProductId,  
  10.             product.ProductName,  
  11.             product.Price,  
  12.             order.Quantity,  
  13.             Customer = cust.Name  
  14.     }).ToList();  

NOTE

  1. Always remember, both the anonymous types should have exact same number of properties with same name and datatype other wise you will get the compile time error.

  2. If one of them is defined NULL and other is defined NOT NULL then we need to do typecasting of NOT NULL field to NULL data type.
LEFT JOIN or LEFT OUTER JOIN

Left Join returns all rows from left table and from right table returns only matched records. If there are no columns matching in the right table crosponding to left table records, it returns NULL values.

In Left Join it is mandatory to use "INTO" keyword and "DefaultIfEmpty()" method

  1. var q = (from cust in dataContext.Customers join product in dataContext.Products on cust.CustomerId equals product.CustomerId into rd from rt in rd.DefaultIfEmpty() orderby cust.CustomerId select new {  
  2.     cust.CustomerId,  
  3.         cust.Name,  
  4.         //You can handle null values do type casting like int?(NULL int)   
  5.         rt.(int ? ) ProductId,  
  6.         rt.ProductName,  
  7.         rt.Price,  
  8. }).ToList();  

NOTE

  1. Always remember; for Right join, just swap the table. In LINQ, there is pre-defined method for right join.

CROSS JOIN

Cross join returns cartesian product of both the tables that means multiplication of number records from both the tables -  each row on left table will be related to each row of right table

  1. var q = (from cust in dataContext.Customers from product in dataContext.Products select new {  
  2.     cust.CustomerId,  
  3.         cust.Name,  
  4.         product.ProductId,  
  5.         product.ProductName,  
  6. }).ToList();  

NOTE

  1. In Cross Join, there is no need to use Join clause and where clause.

GROUP JOIN

A group join produces a sequence of object arrays based on properties equivalence of left collection and right collection.

  1. var q = (from cust in dataContext.Customers join product in dataContext.Products on cust.CustomerId equals product.CustomerId into rd orderby cust.CustomerId select new {  
  2.     cust.CustomerId,  
  3.         cust.Name,  
  4.         Product = rd,  
  5. }).ToList();  

NOTE

  1. If right collection has no matching elements with left collection, then an empty array will be produced.
  2. We can also use the result of a GROUP JOIN as a subquery.

I hope you will enjoy the valuable code. Happy Coding !!!