我使用这段代码(在stackoverflow上找到)来生成谓词
static class BuilderPredicate
{
public static Expression<Func<T, bool>> True<T>() { return f => true; }
public static Expression<Func<T, bool>> False<T>() { return f => false; }
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
return Expression.Lambda<Func<T, bool>>
(Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters);
}
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
return Expression.Lambda<Func<T, bool>>
(Expression.AndAlso(expr1.Body, invokedExpr), expr1.Parameters);
}
}
我有这个对象:
public class Person : IPerson
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public interface IPerson
{
int Id { get; set; }
string FirstName { get; set; }
string LastName { get; set; }
}
要使用,我这样做:
private void CreationPredicate(string fieldname, string stringToSearch)
{
var predicate = BuilderPredicate.True<Person>();
switch (fieldname)
{
case "FirstName":
predicate = predicate.And(e => e.FirstName.StartsWith(stringToSearch));
break;
case "LastName":
predicate = predicate.And(e => e.LastName.StartsWith(stringToSearch));
break;
}
}
我想避免,切换并替换e => e.FirstName.StartWith
(如果可能)
e => e.fieldname.StartWith
我该怎么做?
谢谢,
答案 0 :(得分:4)
如果您正在使用字符串,则需要以艰难的方式构建表达式:
var param = Expression.Parameter(typeof (Foo));
var pred = Expression.Lambda<Func<Foo, bool>>(
Expression.Call(
Expression.PropertyOrField(param, fieldName),
"StartsWith",null,
Expression.Constant(stringToSearch)), param);
在4.0上,我还使用ExpressionVisitor
来重写主体为“和”,而不是Invoke
; EF等不支持Invoke
。
答案 1 :(得分:1)
delegate string StringPropertyGetter(IPerson person);
void CreationPredicate(StringPropertyGetter getter, string stringToSearch)
{
var predicate = BuilderPredicate.True<Person>();
predicate = predicate.And(e => getter(e).StartsWith(stringToSearch));
}
这样打电话:
CreationPredicate(p => p.FirstName, "searchstring");