简体   繁体   English

用多个参数构建表达式树

[英]Build an Expression Tree with multiple parameters

I am trying to create a method that can accept multiple property names and a string value that will be use to research in entity possessing those properties 我正在尝试创建一种可以接受多个属性名称和一个字符串值的方法,该方法将用于研究拥有这些属性的实体

I want to a generic method to replace this one: 我想用一种通用的方法来代替这个方法:

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

So I tried this: 所以我尝试了这个:

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

I do something wrong when I call Expression.Call Is it possible to build an expression like this or i must use concatenate expression? 调用Expression.Call时我做错了事是否可以构建这样的表达式,或者我必须使用串联表达式?

I'm not sure what you want to do with each parameter. 我不确定您想对每个参数做什么。 Assuming that all of the fields are string , and that you want to call StartsWith against each of them, this will work: 假设所有字段都是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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM