A Brief Description Of Deferred Query Operators

Deferred query evaluation is a fundamental LINQ topic that you will learn in this article.

What exactly are LINQ Query Operators?

LINQ Query operators are a collection of extension methods that may be used to perform various actions in the context of LINQ queries. These operators contain the LINQ technology’s heart and soul, and they are the real elements that make LINQ possible.

The list of common query operators and their categories are as follows:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

       What is the definition of Deferred Query Evaluation?

Deferred query evaluation in LINQ means that the LINQ query is not evaluated when it is defined, but instead when it is used. Consider the query definition below.

List items = new List { "one", "two", "three" }; 
 
var allItems = from i in items 
               select i; 
 
foreach (var s in allItems) 
{ 
   Console.WriteLine(s); 
} 
 
items.Add("four"); 
 
foreach (var s in allItems) 
{ 
   Console.WriteLine(s); 
}

The query is specified in the second line of the code snippet above. This will select all of the items and assign the results of the query to the variable all Items. You will get the following output if you execute the for each loop.

one 
two 
three

Then I added another item “four” to the list and ran all Items again without modifying the query, and the second loop returned the following output.

one 
two 
three 
four

The result is different because the query is not evaluated at the time of definition, but rather when iterating through the list of objects using the foreach loop. This means that you may define your query once and use it several times, even if the data in your source sequence has changed. In other words, each time you iterate your query, you will get new results.

A LINQ query, from a logical standpoint, defines a type of “query plan” that will not be performed until it is utilised and will be executed again each time it is run. Consider the following scenario: you want a secure copy of your query results that remains unchanged even if the source sequence changes. You may do this by using conversion operators like ToList or ToArray.

The most of the operators in the above table are deferred query operators, and they are easily identified since they all return IEnumerable or IOrderedEnumerable objects. In my project, I’m developing the following employee class with the basic characteristics to give you an overview of these operators and their examples.

class Employee 
{ 
   public int ID { get; set; } 
   public string Name { get; set; } 
   public decimal Salary { get; set; } 
}

I’m making the following list of objects in the main application. This list will be used as the input sequence in all of the query operator examples following.

List employees = new List(); 
 
employees.Add(new Employee { ID = 1, Name = "Peter", Salary = 10000 }); 
employees.Add(new Employee { ID = 2, Name = "David", Salary = 20000 }); 
employees.Add(new Employee { ID = 3, Name = "Simon", Salary = 25000 }); 
employees.Add(new Employee { ID = 4, Name = "John", Salary = 7000 }); 
employees.Add(new Employee { ID = 5, Name = "Alan", Salary = 3000 });

The rest of this course will provide examples of several of the deferred query operators available in LINQ. Because all query operators are defined as extension methods in the.NET Framework, I’m using extension method syntax in most of the examples below but also providing plain query syntax where applicable.

Where operator

To include just certain components in a sequence, use the Where operator. As an example, the following query may be used to filter out workers with salaries below $10,000.

Extension Method Syntax
var query = employees 
            .Where(emp => emp.Salary < 10000) 
            .Select(emp => emp);
LINQ Query Syntax
var query = from emp in employees 
            where emp.Salary < 10000 
            select emp;

Select operator

A sequence of elements that you choose or dynamically create in your query are returned by the select operator. Additionally, it is capable of generating data types that are distinct from those used in the original sequence. Consider the following instances:

The select operator selects every employee from the list in the example that follows.

Extension Method Syntax
var query = employees 
            .Select(emp => emp);
LINQ Query Syntax
var query = from emp in employees 
            select emp;

The select operator just selects the names of the employees in the example that follows.

Extension Method Syntax
var query = employees 
            .Select(emp => emp.Name);
LINQ Query Syntax
var query = from emp in employees 
            select emp.Name;

The select operator in the example below generates anonymous types on the fly using just the employee ID and salary fields.

Extension Method Syntax
var query = employees 
            .Select(emp => new { emp.ID, emp.Salary });
LINQ Query Syntax
var query = from emp in employees 
            select new { emp.ID, emp.Salary };

Take operator

This operator, which belongs to the group of partitioning operators, starts returning elements from the input sequence at the given position. Consider about the scenario below, where I just want the first three employees from the list.

var query = employees.Take(3);

Skip operator

This operator, which belongs to the category of partitioning operators, skips specified number of elements starting at the beginning of the input sequence. Take into account the next case where I wish to include the first two employees from the list.

var query = employees.Skip(2);

Concat operator

This operator belongs to the group of concatenation operators and enables the joining of several input sequences of the same type into a single output sequence. Take a look at the example below, where I’ve combined the first and last employee.

var first = employees.Take(1); 
var last = employees.Skip(4); 
 
var query = first.Concat(last);

OrderBy operator

An input sequence can be arranged using this sorting operator, which belongs to that class of operations. Think about the scenario below, where I want all the employees shown in order of their salaries.

Extension Method Syntax
var query = employees 
            .OrderBy(emp => emp.Salary) 
            .Select(emp => emp); ​
LINQ Query Syntax
var query = from emp in employees 
            orderby emp.Salary 
            select emp; ​

ThenBy operator

As the OrderBy method’s return type is IOrderedEnumerable, it is possible to reorder it using the ThenBy operator according to any specific requirements, as shown in the example below:

var query = employees 
            .OrderBy(emp => emp.Salary) 
            .ThenBy( emp => emp.Name) 
            .Select(emp => emp);

OrderByDescending and ThenByDescending are more LINQ operators that perform functions similar to OrderBy and ThenBy, including that they order the elements in descending order.

Reverse operator

In reverse order, this operator returns a sequence of the same type as the given sequence. Take a look at the example below where I’m trying to get a list of any employee in reverse order.

var query = employees 
            .Select( emp => emp) 
            .Reverse();

Distinct operator

This set operator, which removes duplicate elements from an input sequence, belongs to that class of operators. Consider the case below.

var list1 = employees.Take(5); 
var list2 = employees.Skip(0); 
 
var list = list1.Concat(list2); 
 
var query = list.Distinct();

I concatenated the elements from lists 1 and 2 to create a single list, generating some duplicate elements in the input sequence list. I then used the distinct operator to remove all of the duplicate elements from the list.

Union operator

This set operator returns a sequence that indicates the set union of the two source sequences. Consider the case below.

var list1 = employees.Take(4); 
var list2 = employees.Skip(1); 
 
var query = list1.Union(list2);

Intersect operator

The set intersection of two source sequences is returned by this set operator, which belongs to that set of operations. Consider the case below.

var list1 = employees.Take(3); 
var list2 = employees.Skip(2); 
 
var query = list1.Intersect(list2);

 

 

Submit a Comment

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

Subscribe

Select Categories