Árvores de expressão em provedores LINQ
Veja como os provedores traduzem expressões em consultas.
Árvores de expressão em provedores LINQ é uma aula grátis de C# Academy no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de C# Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de C# Academy inclui 4 aulas no total.
Por que o LINQ precisa de árvores de expressões
O LINQ tem duas variantes. IEnumerable<T> executa lambdas na memória. IQueryable<T> as recebe como árvores de expressões, para que um provedor possa traduzi-las para outra linguagem, como SQL.
IEnumerable versus IQueryable
A diferença está no tipo do parâmetro: IEnumerable.Where recebe Func<T,bool> (compilado), enquanto IQueryable.Where recebe Expression<Func<T,bool>> (uma árvore).
using System;
using System.Linq;
using System.Linq.Expressions;
int[] nums = { 1, 2, 3, 4 };
// IEnumerable path: lambda is a compiled delegate
var evens = nums.Where(n => n % 2 == 0);
Console.WriteLine(string.Join(",", evens)); // 2,4A consulta permanece como dados
Com IQueryable, sua lambda é capturada como uma árvore de expressões e ainda não é executada. O provedor inspeciona a árvore para construir uma consulta.
using System;
using System.Linq;
using System.Linq.Expressions;
IQueryable<int> q = new[] { 1, 2, 3, 4, 5 }.AsQueryable();
var filtered = q.Where(n => n > 2);
Console.WriteLine(filtered.Expression.NodeType); // Call (a method-call tree)Inspecionando uma expressão de consulta
A propriedade Expression de um objeto consultável expõe a árvore que o provedor traduzirá.
using System;
using System.Linq;
var q = new[] { 10, 20, 30 }.AsQueryable().Where(x => x >= 20);
Console.WriteLine(q.Expression.ToString().Contains("Where")); // TrueTradução, não execução
Um provedor como o Entity Framework percorre a árvore e emite SQL, como WHERE Age > 18. Seu predicado em C# nunca é executado no cliente; o banco de dados faz o trabalho.
O papel de IQueryProvider
IQueryable contém um IQueryProvider. Quando você enumera a consulta, o provedor recebe a árvore de expressões e decide como executá-la.
using System;
using System.Linq;
var q = new[] { 1, 2, 3 }.AsQueryable();
Console.WriteLine(q.Provider.GetType().Name); // EnumerableQuery (the in-memory provider)Execução adiada
A árvore só é traduzida e executada quando você a enumera (por exemplo, com ToList ou foreach). Até lá, ela é apenas dados que você pode continuar compondo.
using System;
using System.Linq;
var q = new[] { 1, 2, 3, 4 }.AsQueryable()
.Where(n => n > 1)
.Select(n => n * 10);
// nothing has run yet; now force it:
Console.WriteLine(string.Join(",", q.ToList())); // 20,30,40Compondo consultas
Como cada operador adiciona algo à árvore de expressões, você pode construir uma consulta em etapas, e o provedor verá tudo no momento da execução.
using System;
using System.Linq;
var baseQuery = new[] { 5, 15, 25, 35 }.AsQueryable();
var q = baseQuery.Where(n => n > 10);
q = q.Where(n => n < 30); // composed: 10 < n < 30
Console.WriteLine(string.Join(",", q.ToList())); // 15,25O que não pode ser traduzido
Os provedores só podem traduzir operações que entendem. Um predicado que chama um método C# arbitrário pode gerar uma exceção durante a execução, pois não há um equivalente em SQL.
Escrevendo seu próprio provedor
Provedores personalizados implementam IQueryProvider e usam um ExpressionVisitor para percorrer a árvore e traduzir cada nó para sua linguagem de consulta de destino.
Reunindo tudo
Isto mostra a ideia principal: a mesma lambda é um delegado para IEnumerable, mas uma árvore para IQueryable, permitindo a tradução.
using System;
using System.Linq;
using System.Linq.Expressions;
Expression<Func<int, bool>> predicate = n => n > 2;
var data = new[] { 1, 2, 3, 4 };
// IEnumerable needs a delegate:
Console.WriteLine(string.Join(",", data.Where(predicate.Compile()))); // 3,4
// IQueryable accepts the tree directly:
Console.WriteLine(string.Join(",", data.AsQueryable().Where(predicate))); // 3,4Verificação rápida
Confirme o papel das árvores de expressões nos provedores LINQ.
Recapitulação
Você aprendeu como os provedores LINQ usam árvores de expressões.
IEnumerableusaFunccompilado;IQueryableusa árvoresExpression<Func>.- Os provedores traduzem a árvore (por exemplo, para SQL) em vez de executá-la.
- A execução é adiada até a enumeração.
- Apenas operações traduzíveis funcionam; métodos arbitrários podem falhar.
Perguntas Frequentes
A aula “Árvores de expressão em provedores LINQ” é grátis?
Sim — o texto completo de “Árvores de expressão em provedores LINQ” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de C# Academy, atualize para CoddyKit PRO. O curso de C# Academy inclui 4 aulas no total.
O que vou aprender em “Árvores de expressão em provedores LINQ”?
Veja como os provedores traduzem expressões em consultas. Você pratica C# Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar C# Academy?
Nenhuma experiência prévia é necessária. C# Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.
Quanto tempo leva a aula “Árvores de expressão em provedores LINQ”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de C# Academy?
Sim. Cada aula de C# Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- O que são árvores de expressão
- Construindo expressões manualmente
- Compilando e executando expressões
- Árvores de expressão em provedores LINQ