我有一个Linq表达式列表,如:
List<Expression<Func<Customer, bool>>>
我需要从搜索页面添加一大堆谓词,例如:
x.Name.Contains(searchString)
x.Description.Contains(searchString)
...
我想创建一个方法,所以我不会得到大量的重复代码。带有签名的东西:
void AddCustomerPredicate(List<Expression<Func<Customer, bool>>> predicates, Expression<Func<Customer, string>> prop, string searchString);
我会用的是:
var predicates = new List<Expression<Func<Customer, bool>>>();
AddCustomerPredicate(predicates, x => x.Name, this.Name);
AddCustomerPredicate(predicates, x => x.Description, this.Description);
...
我已经简化了一点问题,但这就是它的要点。我没有用表达式树等做很多工作,所以我不确定如何实现这个方法?
的 的 **编辑**
我可能过分简化了这个问题。我知道如何添加到predicates.Add(x => x.Name.Contains(this.searchString))
之类的列表中,但是在将每个搜索参数添加到列表之前,我想对每个搜索参数执行各种操作(例如,检查null或为空)。因此,我想在每个搜索参数上调用一个方法,如上所述,所以所有这些东西都可以包含在一个方法中。
答案 0 :(得分:3)
您真正需要的是将Expression<Func<T, string>>
翻译成Expression<Func<T, bool>>
的方法:
public static Expression<Func<T, bool>> GetContainsExpression<T>(Expression<Func<T, string>> prop, string searchString)
{
var method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
var someValue = Expression.Constant(searchString, typeof(string));
var containsMethodExp = Expression.Call(prop.Body, method, someValue);
return Expression.Lambda<Func<T, bool>>(containsMethodExp, prop.Parameters[0]);
}
这是受其他答案的启发:How do I create an expression tree to represent 'String.Contains(“term”)' in C#?
var predicates = new List<Expression<Func<Customer, bool>>>();
predicates.Add(GetContainsExpression((Customer x) => x.Name, this.Name));
predicates.Add(GetContainsExpression((Customer x) => x.Description, this.Description));
答案 1 :(得分:2)
我相信这会做你想要的,也会处理null
属性值(因此调用Contains()
不会抛出):
private static void AddCustomerPredicate(
List<Expression<Func<Customer, bool>>> predicates,
Expression<Func<Customer, string>> accessor,
string searchString)
{
var x = accessor.Parameters[0];
var temp = Expression.Variable(typeof(string), "temp");
var predicate = Expression.Lambda<Func<Customer, bool>>(
Expression.Block(
new[] { temp },
Expression.Assign(
temp,
accessor.Body),
Expression.AndAlso(
Expression.IsFalse(
Expression.ReferenceEqual(
temp,
Expression.Default(typeof(string)))),
Expression.Call(
temp,
"Contains",
Type.EmptyTypes,
Expression.Constant(searchString)))),
x);
predicates.Add(predicate);
}