我没有您的数据模型,因此我使用 Northwind OData 提要为您构建解决方案。
它的作用是遍历一个字典,它定义了一个搜索词和一个要查找的属性。
然后我们构建一个谓词并遍历它的每个 kvp。最后我们从这里返回一个 lambda 函数。
将其视为循环中的谓词构建器:
/*using http://services.odata.org/V3/Northwind/Northwind.svc/ */
//Define a set of KeyValueParis to search for
var keywords = new Dictionary<string, string> {
{"Beverages", "CategoryName"},
{"savory", "Description"},
{"meats", "Description"},
{"Condiments", "CategoryName"}
};
//Create the predicate and initialize it
Expression<Func<Category, bool>> predicate = x => false;
//Define the type
ParameterExpression parameterExp = Expression.Parameter(typeof(Category), "Category");
//Get the Contains method. reference: http://stackoverflow.com/questions/278684/how-do-i-create-an-expression-tree-to-represent-string-containsterm-in-c
MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
//Iterate over each kvp
foreach (var kvp in keywords)
{
var body = predicate.Body;
//set the property or field we are checking against
var memberExpr = Expression.PropertyOrField(parameterExp, kvp.Value);
var constExpr = Expression.Constant(kvp.Key, typeof(string));
var containsMethodExpr = Expression.Call(memberExpr, method, constExpr);
body = Expression.OrElse(body, containsMethodExpr);
predicate = Expression.Lambda<Func<Category, bool>>(body, parameterExp);
}
Categories.Where (predicate).Dump();
输出:
您唯一要做的就是将Category 替换为您的目标类型。如果时间允许,我会将其包装在一个通用方法中并将其添加到此答案中。
Linqpad source
//编辑: 这是构建表达式的静态方法。您只需要提供带有搜索词的Dictionary<string,string>。
static Expression<Func<T, bool>> BuildExpression<T>(Dictionary<string, string> searchTerms)
{
//Create the predicate and initialize it
Expression<Func<T, bool>> predicate = x => false;
//Define the type
ParameterExpression parameterExp = Expression.Parameter(typeof(T), "type");
//Get the Contains method. reference: http://stackoverflow.com/questions/278684/how-do-i-create-an-expression-tree-to-represent-string-containsterm-in-c
MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
//Iterate over each kvp
foreach (var kvp in searchTerms)
{
var body = predicate.Body;
//set the property or field we are checking against
var memberExpr = Expression.PropertyOrField(parameterExp, kvp.Value);
var constExpr = Expression.Constant(kvp.Key, typeof(string));
var containsMethodExpr = Expression.Call(memberExpr, method, constExpr);
body = Expression.OrElse(body, containsMethodExpr);
predicate = Expression.Lambda<Func<T, bool>>(body, parameterExp);
}
return predicate;
}
用法:
var lambda = BuildExpression<Category>(keywords);
Categories.Where(lambda).Dump();