【问题标题】:Building Expression Tree for string.Contains [duplicate]为字符串构建表达式树。包含 [重复]
【发布时间】:2013-01-30 21:59:39
【问题描述】:

我正在努力构建表达式树,以便对某些数据进行动态过滤。

我想出了这个,但在 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(例如“tom”)中的文本进行比较。因此,如果T.Name.Contains("tom"); 我希望查询包含记录,否则不包含。

变量queryIQueryable&lt;T&gt; 类型

编辑:终于可以使用这段代码了:

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

【问题讨论】:

  • "但它在 var lambda = line 处失败" 你有编译时或运行时错误吗?如果有内部异常,你能显示完整的异常吗?
  • @HamletHakobyan,用我当前的代码和错误更新了问题
  • 您将 11 个月前的问答问题标记为可能重复的问题?为什么要打扰?

标签: c# .net-4.0 expression-trees


【解决方案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

所有这些我都是徒手写的,因此有效可能会有所不同。结果表达式应该是这样的

p => p.Name.Contains(val)

【讨论】:

  • rule.Field 是 PropertyName,rule.Data 是我要测试的值是否包含在 rule.Field "rule.Field" .Contains(rule.Data)
  • 我一定是做错了什么,看看我对原帖的编辑,它不太好。
  • 虽然我不能 100% 确定 provider.CreateQuery 中发生了什么,但我认为它实际上并不需要。是查询 IQueryable?如果是,那么你应该做的是return query.Where(lambda)
  • 我明天会先试试!谢谢。
  • 在 Expression.IsFalse 中包装调用表达式
【解决方案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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-22
    • 1970-01-01
    • 1970-01-01
    • 2020-08-25
    • 2019-10-07
    • 2021-11-26
    相关资源
    最近更新 更多