动态IQueryable扩展方法的产生方式

时间:2019-04-08 11:10:26

标签: c# linq methods dynamic iqueryable

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

1 个答案:

答案 0 :(得分: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);