【问题标题】:Expression predicates with field name as parameter以字段名作为参数的表达式谓词
【发布时间】:2012-06-29 05:47:07
【问题描述】:

我使用这段代码(在 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 =&gt; e.FirstName.StartWith

e => e.fieldname.StartWith

我该怎么做?

谢谢,

【问题讨论】:

    标签: c# .net linq linq-to-sql predicate


    【解决方案1】:

    如果您使用的是字符串,则需要以困难的方式构建表达式:

    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重写“and”的正文,而不是 Invoke; EF 等不支持Invoke

    【讨论】:

      【解决方案2】:
      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");
      

      【讨论】:

        猜你喜欢
        • 2015-07-28
        • 2023-03-04
        • 2014-05-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多