构建表达式树的string.Contains [复制](Building Expression Tr

2019-08-16 15:51发布

这个问题已经在这里有一个答案:

  • 如何创建一个表达式树来表示C#“String.Contains(‘术语’)”? 4个回答

我挣扎构建表达式树,所以我可以做动态的一些数据过滤。

我想出了这一点,但在失败var lambda =

foreach (var rule in request.Where.Rules)
{
    var parameterExpression = Expression.Parameter(typeof(string), rule.Field);
    var left = Expression.Call(parameterExpression, typeof(string).GetMethod("ToLower", Type.EmptyTypes));
    var right = Expression.Constant(rule.Data.ToLower());
    var method = typeof(string).GetMethod("Contains", new [] { typeof(string) });
    var call = Expression.Call(left, method, right);
    var lambda = Expression.Lambda<Func<T, bool>>(call, parameterExpression);
    query = query.Where(lambda);
}

var这个rule有哪些我想用文字来比较字段(如“姓名”) rule.Data (EX“嗵”)。 所以,如果T.Name.Contains("tom"); 我希望查询包括备案,否则不能。

了var query的类型是IQueryable<T>

编辑 :终于得到它,此代码的工作:

foreach (var rule in request.Where.Rules)
{
    var parameter = Expression.Parameter(typeof(T), "x");
    var property = Expression.Property(parameter, rule.Field);
    var value = Expression.Constant(rule.Data);
    var type = value.Type; 
    var containsmethod = type.GetMethod("Contains", new[] { typeof(string) });
    var call = Expression.Call(property, containsmethod, value);
    var lambda = Expression.Lambda<Func<T, bool>>(call, parameter);
    query = query.Where(lambda);
}

Answer 1:

你是几乎没有,但你的参数的表述应该是类型的T ,不是String ,你也缺少表达式正从类型属性T喜欢的名字。

你应该有大致是这样的

val -> Expression.Constant(typeof(string), rule.Field)
parameter -> Expression.Parameter(typeof(T), "p")
property -> Expression.Property(parameter, "PropertyName")
contains -> Expression.Call(property, containsmethod, val)
equals true -> Expression.True or equals, something like that

我freehanding了这一切,所以它很可能有所不同是有效的。 所得的表达应该是这样的

p => p.Name.Contains(val)


Answer 2:

如果你想创建Where查询,您必须创建lambda然后调用Where的查询,并通过lambda 。 试试这个:

Expression<Func<T, bool>> lambda = Expression.Lambda<Func<T, bool>>(call, parameter);
MethodCallExpression expression = Expression.Call(typeof(Queryable), "Where",
                                    new[] { typeof(T) }, query.Expression, lambda);
query = query.Provider.CreateQuery<T>(expression);

代替

var result = Expression.IsTrue(call);
query = query.Provider.CreateQuery<T>(result);


文章来源: Building Expression Tree for string.Contains [duplicate]