正如标题所说,如果字符串列表中的任何项目与Book对象的字符串匹配,我正在尝试生成用于检查的表达式树。
到目前为止,我已经得到了这个:
private static Expression<Func<Books, bool>> GenerateListContainsLikeExpression(string propertyName, List<string> values)
{
var parameter = Expression.Parameter(typeof(Books), "b");
var listParameter = Expression.Parameter(typeof(string), "v");
var property = Expression.Property(parameter, propertyName);
var anyMethod = typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public).First(m => m.Name == "Any" && m.GetParameters().Count() == 2).MakeGenericMethod(typeof(string));
var toStringMethod = typeof(object).GetMethod("ToString");
var containsMethod = typeof(string).GetMethod("Contains");
var objectString = Expression.Call(property, toStringMethod);
var lambda = Expression.Call(listParameter, containsMethod, objectString);
var func = Expression.Lambda<Func<List<string>, bool>>(lambda, parameter);
var comparison = Expression.Call(anyMethod, Expression.Constant(values), func);
return Expression.Lambda<Func<Books, bool>>(comparison, parameter);
}
但是我收到了这个错误:
类型'System.Boolean'的表达式不能用于'System.Func
2[System.String,System.Boolean]' of method 'Boolean Any[String](System.Collections.Generic.IEnumerable
1 [System.String],System.Func`2 [System.String,System.Boolean])'类型的参数
在这一行:
var comparison = Expression.Call(anyMethod, Expression.Constant(values), lambda);
我觉得我只需要最后一点。
提前致谢: - )
编辑:澄清。我会更详细地解释一下我需要什么。
我需要根据一些书籍属性对书籍进行分类。在这种特定情况下,我将一个字符串列表传递给该函数。我需要检查这些字符串是否包含在任何书籍标题中。
首先,我认为我需要的lambda开头是错误的。这是我实际需要的lambda:b => values.Any(v => b.Title.ToString().Contains(v))
这是我最终的最终代码:
private static Expression<Func<Books, bool>> GenerateListContainsLikeExpression(string propertyName, List<string> values)
{
var parameter = Expression.Parameter(typeof(Books), "b");
var listParameter = Expression.Parameter(typeof(string), "v");
var property = Expression.Property(parameter, propertyName);
var anyMethod = typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public).First(m => m.Name == "Any" && m.GetParameters().Count() == 2).MakeGenericMethod(typeof(string));
var toStringMethod = typeof(object).GetMethod("ToString");
var containsMethod = typeof(string).GetMethod("Contains");
var objectString = Expression.Call(property, toStringMethod);
var lambda = Expression.Call(objectString, containsMethod, listParameter);
var func = Expression.Lambda<Func<string, bool>>(lambda, listParameter);
var comparison = Expression.Call(anyMethod, Expression.Constant(values), func);
return Expression.Lambda<Func<Books, bool>>(comparison, parameter);
}
答案 0 :(得分:3)
最终工作代码:
private static Expression<Func<Books, bool>> GenerateListContainsLikeExpression(string propertyName, List<string> values)
{
var parameter = Expression.Parameter(typeof(Books), "b");
var listParameter = Expression.Parameter(typeof(string), "v");
var property = Expression.Property(parameter, propertyName);
var anyMethod = typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public).First(m => m.Name == "Any" && m.GetParameters().Count() == 2).MakeGenericMethod(typeof(string));
var toStringMethod = typeof(object).GetMethod("ToString");
var containsMethod = typeof(string).GetMethod("Contains");
var objectString = Expression.Call(property, toStringMethod);
var lambda = Expression.Call(objectString, containsMethod, listParameter);
var func = Expression.Lambda<Func<string, bool>>(lambda, listParameter);
var comparison = Expression.Call(anyMethod, Expression.Constant(values), func);
return Expression.Lambda<Func<Books, bool>>(comparison, parameter);
}
有关问题的更深入解释。请参阅原帖中的我的编辑。