English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

LINQ Deferred Execution Query

Lazy execution means that the evaluation of the expression is delayed until it is actually needed. It greatly improves performance by avoiding unnecessary execution.

Lazy execution is applicable to any in-memory collection as well as remote LINQ providers, such as LINQ-to-SQL, LINQ-to-Entities, LINQ-to-XML, etc.

Let's understand lazy execution with the following example:

deferred execution

In the above example, you can see that the query is implemented and executed when iterating over the foreach loop. This is called lazy execution. When you actually access each object in the collection and process it, LINQ handles the studentList collection.

Lazy execution will return the latest data

To check if the lazy execution always returns the latest data, add a teenager student after the foreach loop and check the list of teenage students:

deferred execution

As you can see, the second foreach loop executes the query again and returns the latest data. Lazy execution recalculates each time it is executed; this is calledLazy evaluation. This is one of the main advantages of lazy execution: it always provides you with the latest data.

implement lazy execution

You can use c# to yield Custom extension methods with the keyword IEnumerable implement lazy execution.

For example, you can implement a custom extension method GetTeenAgerStudents for IEnumerable that returns a list of all teenage students.

public static class EnumerableExtensionMethods
{
    public static IEnumerable<Student> GetTeenAgerStudents(this IEnumerable<Student> source)
    {
        foreach (Student std in source)
        {
            Console.WriteLine("Accessing student {0}", std.StudentName);
            if (std.age > 12 && std.age < 20)
                yield return std;
        }
    }
}

Please note that every time GetTeenAgerStudents() is called, we print the student's name on the console.

Now, you can use the following extension methods:

    C#:

IList<Student> studentList = new List<Student>() { 
            new Student() { StudentID = 1, StudentName = "John", 13 },
            new Student() { StudentID = 2, StudentName = "Steve", 15 },
            new Student() { StudentID = 3, StudentName = "Bill", 18 },
            new Student() { StudentID = 4, StudentName = "Ram", age = 12 },
            new Student() { StudentID = 5, StudentName = "Ron", age = 21 } 
        }
            
var teenAgerStudents = from s in studentList.GetTeenAgerStudents() 
                        select s;
foreach (Student teenStudent in teenAgerStudents)
    Console.WriteLine("Student Name: {0}", teenStudent.StudentName);
Output:
Accessing student John
Student Name: John
Accessing student Steve
Student Name: Steve
Accessing student Bill
Student Name: Bill
Accessing student Ram
Accessing student Ron

As can be seen from the output, GetTeenAgerStudents() will be called when you use the foreach loop to iterate over studentList.

deferred execution

Therefore, in this way, you can useyieldCreate custom methods with keywords to gain the advantages of deferred execution.