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

Ejecución diferida de consultas LINQ

La ejecución diferida significa que la evaluación de la expresión se retrasa hasta el momento en que realmente se necesita. Evitando la ejecución innecesaria, mejora enormemente el rendimiento.

La ejecución diferida es aplicable a cualquier colección en memoria y proveedores remotos de LINQ, como LINQ-a-SQL, LINQ-a-Entities, LINQ-a-XML, etc.

Vamos a usar el siguiente ejemplo para entender la ejecución diferida:

Ejecución diferida

En el ejemplo anterior, puede ver que al iterar con el bucle foreach se ha implementado y ejecutado la consulta. Esto se llama ejecución diferida. Cuando realmente accede a cada objeto en la colección y lo procesa, LINQ maneja la colección studentList.

La ejecución diferida devolverá los datos más recientes

Para verificar si la ejecución diferida devuelve los datos más recientes cada vez, agregue un estudiante adolescente más en el bucle foreach y verifique la lista de estudiantes adolescentes:

Ejecución diferida

Como puede ver, el segundo bucle foreach ejecuta la consulta nuevamente y devuelve los datos más recientes. La ejecución diferida recalcula en cada ejecución; esto se llamaEvaluación perezosa. Esto es una de las principales ventajas de la ejecución diferida: siempre le brinda los datos más recientes.

para implementar ejecución diferida

Puede usar c# yield La implementación de métodos de extensión personalizados para IEnumerable realiza ejecución diferida.

Por ejemplo, puede implementar un método de extensión personalizado GetTeenAgerStudents para IEnumerable, que regresará una lista de todos los estudiantes adolescentes.

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

Tenga en cuenta que cada vez que se llama a GetTeenAgerStudents(), imprimimos el nombre del estudiante en la consola.

Ahora, puede usar los siguientes métodos de extensión:

    C#:

IList<Student> studentList = new List<Student>() { 
            new Student() { StudentID = 1, StudentName = "John", age = 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("Nombre del estudiante: {0}", teenStudent.StudentName);
Salida:
Accediendo a estudiante John
Nombre del estudiante: John
Accediendo a estudiante Steve
Nombre del estudiante: Steve
Accediendo a estudiante Bill
Nombre del estudiante: Bill
Accediendo a estudiante Ram
Accediendo a estudiante Ron

Como se puede ver en la salida, GetTeenAgerStudents() se llama cuando se itera studentList con foreach.

Ejecución diferida

Por lo tanto, de esta manera, puede usaryieldCree métodos personalizados con palabras clave para obtener ventajas de ejecución diferida.