The current article continues the series about LINQ. The previous part introduced the LINQ technologies and demonstrated its usage on some basic examples and a couple of more advanced coding challenges. The current article will further expose different ways to write LINQ query operations.
LINQ queries can be written in two syntax types, a Query Syntax and a Method Syntax.
Set the stage
We start with the same data structure and examples from the last article. Assume that we have a class, where the Student is defined as follows:
public class Student
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int BirthYear { get; set; }
public enum GenderType { Female, Male };
public GenderType Gender { get; set; }
public string Interests { get; set; }
}
The list of students is defined like below:
List<Student> students = GetStudents(); //Some arbitrary method that return a list of Students
Besides, our data model gets extended with some new classes:
public class Teacher
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Subject
{
public int Id { get; set; }
public string Name { get; set; }
public int Capacity { get; set; }
public int TeacherId { get; set; }
}
Thus, we have Teachers and Subjects. Each Subject can have only one Teacher.
Query Expression Syntax in LINQ
LINQ Query syntax structure is similar to SQL query structure. For example, a query to get the ID and the student’s First and Last Names from a list of students would look like below:
var studentsInfo = from m
in students
select new {
m.Id,
m.FirstName,
m.LastName
};
If we compare it with the corresponding SQL query, we can see a similar structure.
SELECT
m.ID,
m.FirstName,
m.LastName
FROM
Students m
The following example shows the structure of a basic Query Expression syntax:
var results = from m
in objectCollection
where condition
select m;
- m – range variable
- objectCollection – IEnumerable or IQueryable collection
- condition – conditional lambda expression
Method Extension Syntax in LINQ
Method syntax is also known as Fluent syntax. It grounds on extension methods included in the Enumerable and Queryable static classes.
Usage of these extension methods is similar to usage of any other extension methods. The above query in Fluent syntax would look like:
var studentsInfo = students.Select(m => new {
m.Id,
m.FirstName,
m.LastName
});
So, in general, a Fluent query has the following structure:
var results = objectCollection
.Where(m => condition)
.Select(m => m);
- m – range variable
- objectCollection – IEnumerable or IQueryable collection
- condition – conditional lambda expression
LINQ Query Syntax comparison
The following tables show corresponding generic queries side-by-side three syntaxes (for simplicity, we will use the letter m as a reference to the object in all queries).
Retrieve selected properties from all objects in the collection
Query Syntax | Method Syntax | SQL |
from m in table_name select new { m.field1, m.field2, … }; | table_name .Select(m => new { m.column1, m.column2, … }); | SELECT m.column1, m.column2, … FROM table_name m |
Retrieve selected properties from objects in the collection that match the filter conditions
Query Syntax | Method Syntax | SQL |
from m in table_name where condition select new { m.field1, m.field2, … }; | table_name .Where(m => condition) .Select(m => new { m.column1, m.column2, … }); | SELECT m.column1, m.column2, … FROM table_name m WHERE condition; |
Retrieve first N objects filtered by some condition ordered by selected parameters and direction
Query Syntax | Method Syntax | SQL |
from m in table_name where condition orderby m.column1 ascending, m.column2 descending … select new { m.field1, m.field2, … }; | table_name .Where(m => condition) .Select(m => new { m.column1, m.column2, … }) .OrderBy(m =>m.column1) .ThenByDescendin g(m => m.LastName) …; | SELECT TOP N m.column1, m.column2, … FROM table_name m WHERE condition ORDER BY m.column1 ASC, m.column2 DESC … |
Retrieve information from object collections that are connected by some key
Query Syntax | Method Syntax | SQL |
from m in table_name1 join n in table_name2 on m.foreign_key equals n.key select new { m.field1, m.field2, … }; | table_name1 .Join(table_name 2, m => m.foreign_key, n => n.key, (m, n) => new { m.column1, m.column2, … }); | SELECT m.column1 ,m.column2 ,n.column1 ,n.column2 FROM table_name1 m INNER JOIN table_name2 n ON n.key = m.foreign_key |
To put things into perspective, let’s see query examples from above through our example classes.
Query Description | Query Syntax | Method Syntax | SQL |
Get first and last name for all students | from m in students select new { m.FirstName, m.LastName }; | students .Select(m => new { m.FirstName, m.LastName }); | SELECT FirstName, LastName FROM Students |
Get first and last name for all female students | from m in students where m.Gender == 0 select new { m.FirstName, m.LastName }; | students .Where(m => m.Gender == 0) .Select(m => new { m.FirstName, m.LastName }) | SELECT FirstName, LastName FROM students WHERE Gender = 0 |
Get first and last name for first 10 female students ordered alphabetically by the last name | (from m in students where m.Gender == 0 orderby m.LastName select new { m.FirstName, m.LastName }) .Take(10); | students .Where(m => m.Gender == 0) .Select(m => new { m.FirstName, m.LastName }) .OrderBy(m => m.LastName) .Take(10); | SELECT TOP 10 FirstName, LastName FROM students WHERE Gender = 0 ORDER BY LastName |
Get subject ID, Name and first and last name of the teacher for all subjects | from m in subjects join n in teachers on m.TeacherId equals n.Id select new { m.Id, m.Name, m.Capacity, n.FirstName, n.LastName }; | subjects .Join(teachers, m => m.TeacherId, n => n.Id, (m, n) => new { m.Id, m.Name, m.Capacity, n.FirstName, n.LastName }); | SELECT m.ID ,m.Name ,n.FirstName ,n.LastName FROM subjects m INNER JOIN teachers n ON t.Id = m.TeacherId |
Conclusion
We have exposed the two syntaxes and concepts of LINQ technologies. The choice of the right method to write LINQ query operations will probably depend on other technologies and languages used. The good thing about LINQ (besides it is awesome) is that it allows you to choose which syntax suits your style.
If you haven’t already chosen your favorite LINQ flavor, I hope the examples in this article will help you choose the best one for you.
Read more about LINQ
LINQ in C#: A tutorial with Query Examples in LINQ to Objects
LINQ to Entities – Tutorial with Examples
LINQ: Dynamic Creation of Query Filters
Tags: linq, query optimization, syntax Last modified: October 03, 2022