【问题标题】:Build an Expression Tree with multiple parameters构建具有多个参数的表达式树
【发布时间】:2015-12-10 21:19:51
【问题描述】:

我正在尝试创建一个可以接受多个属性名称和一个字符串值的方法,该方法将用于研究拥有这些属性的实体

我想要一个通用的方法来代替这个:

    public static Client[] GetClientByInfo(string info)
    {
        return Context.Db.Clients.Where(c =>
            c.LastName.Contains(info) ||
            c.FirstName.Contains(info)).ToArray();
    }

所以我尝试了这个:

    public static T[] FindByText<T>(string text, string[] properties)
        where T: class
    {
        return Context.Db.Set<T>().AsNoTracking().Where(PropertyEquals<T, string>(properties, text)).ToArray();
    }

    public static Expression<Func<TItem, bool>> PropertyEquals<TItem, TValue>(string[] properties, TValue value)
    {
        MethodInfo startWithMethod = typeof(string).GetMethod("StartsWith", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(string) }, null);
        ParameterExpression parameter = Expression.Parameter(typeof(TItem));
        ConstantExpression constant = Expression.Constant(value, typeof(TValue));
        MemberExpression[] members = new MemberExpression[properties.Length];
        for (int i = 0; i < properties.Length; i++)
            members[i] = Expression.Property(parameter, properties[i]);

        MethodCallExpression callExp = Expression.Call(parameter, startWithMethod, members);

        return Expression.Lambda<Func<TItem, bool>>(callExp, parameter);
    }

我在调用 Expression.Call 时做错了 是否可以构建这样的表达式或者我必须使用连接表达式?

【问题讨论】:

    标签: c# lambda expression-trees


    【解决方案1】:

    我不确定你想对每个参数做什么。假设所有字段都是string,并且您想针对每个字段调用StartsWith,这将起作用:

    public static Expression<Func<TItem, bool>> PropertyEquals<TItem>(string[] properties, string value)
    {
        MethodInfo startWithMethod = typeof(string).GetMethod("StartsWith", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(string) }, null);
        ParameterExpression parameter = Expression.Parameter(typeof(TItem));
        ConstantExpression constant = Expression.Constant(value);
        MemberExpression[] members = new MemberExpression[properties.Length];
        for (int i = 0; i < properties.Length; i++)
            members[i] = Expression.Property(parameter, properties[i]);
    
        Expression predicate = null;
        foreach (var item in members)
        {
            MethodCallExpression callExp = Expression.Call(item, startWithMethod, constant);
            predicate = predicate == null 
                ? (Expression)callExp
                : Expression.OrElse(predicate, callExp);
        }
    
        return Expression.Lambda<Func<TItem, bool>>(predicate, parameter);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多