Marco Baccaro
MCP • MCT • MCAD • MCSD • MCTS • MCPD Enterprise App Dev
Expression Linq
Existe uma classe responsável para cada parte de uma expressão lógica. A tabela abaixo destaca as respectivas classes.
| Expression | Fornece um método estático para criar outros objetos de expressão. |
| BinaryExpression | Representa uma expressão com uma operador binário. Ex: >, <, !=, == e etc. |
| ConstantExpression | Representa uma referência constante em uma expressão. Ex: 50 de typeof(int), “Olá” de typeof(string) e etc. |
| MemberExpression | Representa a referência de um membro (membro obtido por reflection). Ex: Propriedade qualquer de um objeto, x.Id > 10. |
| UnaryExpression | Representa uma operação unária na expressão. Ex: Negativo de um valor. |
A imagem abaixo ilustra a divisão lógica da expressão, no qual cada item é composto por uma classe.

Para ilustrar a utilização do consultas linq dinâmicas, criei um exemplo utilizando linq to object no qual a condição da filtragem (clausula where), será criado em tempo de execução. Para o exemplo criei uma entidade complex type chamado Student para o exemplo:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ExpressionLinqSample {
public class Student {
public int Id { get; set; }
public int Registry { get; set; }
public string Name { get; set; }
}
}
Nessa classe que denominei DynamicLinq, crio a expressão linq baseado nos parâmetros informados pelo usuário na UI:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Reflection;
namespace ExpressionLinqSample {
public class DynamicLinq {
static public Expression<Func> MakeExpression(int field, int paramFromUi) {
Type type = typeof(Student);
ParameterExpression paramExp = Expression.Parameter(type, "Student");
MemberInfo studentyProperty = null;
switch (field) {
case 1:
studentyProperty = type.GetProperty("Id");
break;
case 2:
studentyProperty = type.GetProperty("Registry");
break;
}
MemberExpression memberExp = Expression.MakeMemberAccess(paramExp, studentyProperty);
ConstantExpression constExp = Expression.Constant(paramFromUi, typeof(int));
BinaryExpression binExp = Expression.GreaterThanOrEqual(memberExp, constExp);
return Expression<Func<Student, bool>>.Lambda<Func<Student, bool>>(binExp, paramExp);
}
}
}
Esse é método Main de uma aplicação console para iniciar o programa e consumirmos o método de criação de consulta dinâmica. Veja que o expression delegate é criado a partir da consulta dinâmica criado. Como um delegate, ele executará o algoritmo confeccionado em runtime.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
namespace ExpressionLinqSample {
class Program {
static void Main(string[] args) {
List<Student> students = new List<Student>() {
new Student{Id = 10, Registry=100, Name="Paulo"},
new Student{Id = 20, Registry=200, Name="Pedro"},
new Student{Id = 50, Registry=300, Name="Felipe"},
new Student{Id = 60, Registry=400, Name="Lucas"}
};
Expression<Func<Student, bool>> expression = DynamicLinq.MakeExpression(1, 50);
IEnumerable resultStudents = students.Where(expression.Compile());
foreach (Student item in resultStudents) {
Console.WriteLine(item.Name);
}
}
}
}
Veja abaixo o conteúdo da instância do delegate chamado “expression” na janela Immediate do Visual Studio, nada mais que uma instrução lambda final:

De forma totalmente dinâmica criamos a condição linq “tal que Student.Id seja maior ou igual a 50″. E assim poderíamos ter criado inumeras outras condições que satisfaça uma regra de negócio, bem como formulário de pesquisa baseado nos filtros desejado pelo usuário. Até +.
Marco, parabéens pelo post como sempre enriquecendo o blog =) e também minha mente rs
Excelente Post Prof.!!Agradeço de antemão por ter aprendido bastante com vc no mês passado no módulo 10266 da Ka Solution nos módulos de sábado.Graças as suas aulas finais, finalmente aprendi Delegates,Lambdas,e outros assuntos do curso que eram lacunas grandes pra mim!!Gratidão eterna cara!!
Gde Abraço!!
Tem que adicionar alguma referência ao projeto?
Pois a declaração Expression esta retornando um erro.
[Error 1 Using the generic type 'System.Func' requires 10 type arguments D:\ModuloDeRelatoriosLMS\ProjetosTestes\LinqExpression\LinqExpression\DinamicLinq.cs 14 34 LinqExpression]
E quanto a declaração ?
List students = new List()
O Type List não é reconhecido!
Na publicação do post, por ter o caracter “<", o blog removeu a informação. Esse list é um list genérico da Student, assim List list = new List().
Abs
Show de bola Marcos, e quanto ao erro na declaração
Static public Expression MakeExpression(int field, int paramFromUi) {
[Error 1 Using the generic type 'System.Func' requires 10 type arguments D:\ModuloDeRelatoriosLMS\ProjetosTestes\LinqExpression\LinqExpression\DinamicLinq.cs 14 34 LinqExpression]
Bom dia Marcos, não sei se entendeu a minha pergunta.
Mas na declaração do método MakeExpression da classe DynamicLinq esta retornando um erro.
static public Expression MakeExpression(int field, int paramFromUi) {
ERROR:
[Error 1 Using the generic type ‘System.Func’ requires 10 type arguments
Abs