رضا چوپانی
رضا چوپانی

Reputation: 11

How to generate dynamic IQueryable extension method

public static IQueryable<T> DynamicFilter<T>(this IQueryable<T> query, string Property, dynamic value) where T : class
{
    return query.Where(x => x.GetType().GetProperty(Property) == value).AsQueryable();
}

Upvotes: 0

Views: 727

Answers (1)

Marc Gravell
Marc Gravell

Reputation: 1062745

the trick here is to look at what the compiler does, i.e. compile something like:

using System.Linq;

public class C {
    public void M() {
        var query = Data.Where(x => x.Bar == "abc");
    }
    System.Linq.IQueryable<Foo> Data;
    class Foo {
        public string Bar {get;set;}
    }
}

and see what it does; if we look in sharplab.io, we see:

public void M()
{
    IQueryable<Foo> data = Data;
    ParameterExpression parameterExpression = Expression.Parameter(typeof(Foo), "x");
    BinaryExpression body = Expression.Equal(Expression.Property(parameterExpression, (MethodInfo)MethodBase.GetMethodFromHandle((RuntimeMethodHandle)/*OpCode not supported: LdMemberToken*/)), Expression.Constant("abc", typeof(string)));
    ParameterExpression[] obj = new ParameterExpression[1];
    obj[0] = parameterExpression;
    IQueryable<Foo> queryable = Queryable.Where(data, Expression.Lambda<Func<Foo, bool>>(body, obj));
}

and we can infer that you want something similar, i.e.

var p = Expression.Parameter(typeof(T), "x");
var body = Expression.Equal(
    Expression.PropertyOrField(p, Property),
    Expression.Constant((object)value)
);
var lambda = Expression.Lambda<Func<T, bool>>(body, p);
return query.Where(lambda);

Upvotes: 1

Related Questions