【问题标题】:Combining expressions from list of expressions组合表达式列表中的表达式
【发布时间】:2013-12-09 17:06:19
【问题描述】:

我想使用 LINQ to SQL 创建动态查询生成器

为此,我创建了在

中添加每个动态条件的界面
List<Expression<Func<T,bool>>>

界面如下:

public interface IExpression<T>
{
    IExpression<T> AddWhere(Expression<Func<T,bool>> whereCriteria);    
}

现在我想将列表中的所有表达式组合起来,用“and”条件构造 where 子句并执行查询。

我尝试过组合表达式,但没有成功。

有人可以帮忙吗?或者请提出任何其他替代方案。

【问题讨论】:

    标签: c# dynamic expression


    【解决方案1】:

    最简单的方法是使用 PredicateBuilder:http://www.albahari.com/nutshell/predicatebuilder.aspx

    基本上,您所要做的就是使用这个帮助类:

    using System;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Collections.Generic;
    
    public static class PredicateBuilder
    {
      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 static Expression<Func<Product, bool>> ContainsInDescription (
                                                    params string[] keywords)
      {
        var predicate = PredicateBuilder.False<Product>();
        foreach (string keyword in keywords)
        {
          string temp = keyword;
          predicate = predicate.Or (p => p.Description.Contains (temp));
        }
        return predicate;
      }
    

    (代码和示例均取自上面的链接,我只是在这里发布,以防链接有时不起作用)。

    由于您的界面不使用泛型这一事实,您的特定场景有些复杂。您能否多展示一些相关代码,以便我帮助您更好地根据您的实际需求定制此解决方案?

    【讨论】:

    • 感谢您的回复。我正在研究提供的链接。我的界面使用泛型。我已经修改过了。
    • @user2249600:好吧,如果是这样,那应该是一个简单的复制粘贴问题。请注意,当您 Anding 值时,您应该使用 PredicateBuilder.True&lt;T&gt;(); 初始化谓词
    • 很棒的发现!我不明白这怎么没有得到更多的支持。
    • code project中还有另一篇很棒的文章。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多