C# 为string.Contains生成表达式树

C# 为string.Contains生成表达式树,c#,.net-4.0,expression-trees,C#,.net 4.0,Expression Trees,我正在努力构建一个表达式树,以便能够动态地对一些数据进行过滤 我已经想到了这个,但是它在var lambda=行失败了 foreach (var rule in request.Where.Rules) { var parameterExpression = Expression.Parameter(typeof(string), rule.Field); var left = Expression.Call(parameterExpression, typeof(string)

我正在努力构建一个表达式树,以便能够动态地对一些数据进行过滤

我已经想到了这个,但是它在
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);
}

您就快到了,但是您的参数表达式应该是
T
类型,而不是
String
,您还缺少从类型
T
中获取属性的表达式,比如name

你大概应该有这个

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
我对所有这些都是免费的,所以它的有效性可能有所不同。结果表达式应该是这样的

p => p.Name.Contains(val)

如果要创建
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);
Expression lambda=Expression.lambda(调用,参数);
MethodCallExpression expression=expression.Call(typeof(Queryable),“Where”,
新[]{typeof(T)},query.Expression,lambda);
query=query.Provider.CreateQuery(表达式);
而不是

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

“但它在var lambda=行失败”您有编译时或运行时错误吗?你能用内部异常(如果有的话)显示完全异常吗?@HamletHakobyan,用我当前的代码更新了问题,以及你将11个月前的问答问题标记为可能重复的错误?为什么要麻烦呢?rule.Field是PropertyName,rule.Data是我试图测试它是否包含在rule.Field中的值。Field
“rule.Field”。Contains(rule.Data)
我一定是做错了什么,请参阅我对原始帖子的编辑,它没有完全起作用。虽然我不能100%确定provider.CreateQuery中发生了什么,我认为实际上不需要它。查询是否可查询?如果是,那么您应该做的是
返回查询。Where(lambda)
我明天第一件事就是试试!谢谢。将调用表达式包装在expression.IsFalse中
var result = Expression.IsTrue(call);
query = query.Provider.CreateQuery<T>(result);