Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic LINQ Expression

Tags:

c#

linq

I'm trying to implement this How to specify dynamic field names in a Linq where clause? and getting a compiler error that says:

Cannot resolve method 'Where(System.Linq.Expressions.LambdaExpression

public class Employee
{
    public string Name { get; private set; }
    public int Salary { get; private set; }

    public Employee(string name, int salary)
    {
        Name = name;
        Salary = salary;
    }
}

Then in main method of console app

var employees = new List<Employee>
{
    new Employee("Bob", 45000),
    new Employee("Jane", 25000),
    new Employee("Jim", 5)
};

var eParam = Expression.Parameter(typeof(Employee), "e");

var comparison = Expression.Lambda(
    Expression.LessThan(
        Expression.Property(eParam, "Salary"),
        Expression.Constant(40000)),
    eParam);
var c = from e in employees.Where(comparison) // COMPILER ERROR HERE!!!
    select new {e.Name, e.Salary};

I'm using System.Linq and System.Linq.Expressions. What am I doing wrong here?

EDIT:

The answer is to strongly type the comparison variable and call Compile on it like

var comparison = Expression.Lambda<Func<Employee, bool>>(
    Expression.GreaterThan(
        Expression.Property(eParam, "Salary"),
        Expression.Constant(40000)),
    eParam).Compile();

The query can also be written in method syntax like

var b = employees.Where(comparison);

Instead of calling .Compile(), one can call .AsQueryable() before .Where() on employees also.

like image 512
reggaeguitar Avatar asked Dec 16 '25 11:12

reggaeguitar


1 Answers

  1. Your expression has to be strongly typed:

    var comparison = Expression.Lambda<Func<Employee, bool>>(... 
    
  2. Source has to be IQueryable. Call AsQueryable() on your list before calling Where.

like image 154
MarcinJuraszek Avatar answered Dec 19 '25 07:12

MarcinJuraszek



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!