为 List.Any(v => v.Contains(Book.Title.ToString())) 生成表达式树
Generating Expression Tree for List.Any(v => v.Contains(Book.Title.ToString()))
正如标题所说,如果字符串列表中的任何项目与一本书的字符串匹配,我正在尝试生成一个表达式树来检查 object。
到目前为止我得到了这个:
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);
}
但是我收到这个错误:
Expression of type 'System.Boolean' cannot be used for parameter of type 'System.Func2[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);
}
最终工作代码:
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);
}
为了更深入地解释问题。请参阅我在原文中的编辑 post。
正如标题所说,如果字符串列表中的任何项目与一本书的字符串匹配,我正在尝试生成一个表达式树来检查 object。
到目前为止我得到了这个:
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);
}
但是我收到这个错误:
Expression of type 'System.Boolean' cannot be used for parameter of type '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);
}
最终工作代码:
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);
}
为了更深入地解释问题。请参阅我在原文中的编辑 post。