如何生成动态IQueryable扩展方法

问题描述 投票:0回答:1
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();
}
c# linq methods dynamic iqueryable
1个回答
1
投票

这里的技巧是看看编译器做了什么,即编译类似的东西:

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;}
    }
}

看看它做了什么;如果我们look in sharplab.io,我们看到:

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));
}

我们可以推断你想要类似的东西,即

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);
© www.soinside.com 2019 - 2024. All rights reserved.