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

Consultas de Execução Atrasada LINQ

A execução diferida significa que a avaliação da expressão é adiada até o momento necessário. Ela evita a execução desnecessária, aumentando significativamente o desempenho.

A execução diferida é aplicável a qualquer coleção em memória e fornecedores remotos LINQ, como LINQ-to-SQL, LINQ-to-Entities, LINQ-to-XML, etc.

Vamos usar o seguinte exemplo para entender a execução diferida:

execução atrasada

No exemplo acima, você pode ver que a consulta foi implementada e executada ao iterar com o loop foreach. Isso é chamado de execução diferida. Quando você realmente acessa cada objeto na coleção e o processa, o LINQ lida com a coleção studentList.

A execução diferida retornará os dados mais recentes

Para verificar se a execução diferida retorna sempre os dados mais recentes, adicione um aluno adolescente adicional após o loop foreach e verifique a lista de alunos adolescentes:

execução atrasada

Como você vê, o segundo loop foreach executa a consulta novamente e retorna os dados mais recentes. A execução diferida recalcula-se a cada execução; isso é chamado deEvaluação Preguiçosa. Esta é uma das principais vantagens da execução diferida: ela sempre oferece os dados mais recentes.

Implementação de execução diferida

Você pode usar c# yield A implementação de extensão de método personalizada para IEnumerable realiza a execução diferida.

Por exemplo, você pode implementar uma extensão de método personalizada GetTeenAgerStudents para IEnumerable, que retornará a lista de todos os alunos adolescentes.

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

Atenção, a cada vez que GetTeenAgerStudents() for chamado, teremos uma impressão do nome do aluno no console.

Agora, você pode usar os seguintes métodos de extensão:

    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("Nome do Aluno: {0}", teenStudent.StudentName);
Saída:
Acessando aluno John
Nome do Aluno: John
Acessando aluno Steve
Nome do Aluno: Steve
Acessando aluno Bill
Nome do Aluno: Bill
Acessando aluno Ram
Acessando aluno Ron

Como pode ser visto na saída, GetTeenAgerStudents() será chamado ao iterar studentList com um loop foreach.

execução atrasada

Dessa forma, você pode usaryieldCrie métodos personalizados usando palavras-chave para obter a vantagem de execução atrasada.