C#Lambda - Where - 多个相同标准的表达式

时间:2015-09-23 10:50:05

标签: c# lambda expression

假设 - 派对商店希望根据其数据库中的条件选择人员。

数据库名称“BirthDays”字段:日,月,年

“where”需要是动态的,以便为搜索实例考虑每个因素:

  1. 日= 12,月= 1,年= 1962
  2. 日= 3,月= 4,年= 1977;日= 13,月= 4,年= 1977
  3. 日= 20,月= 8,年= 1941; Day = 9,Month = 1,Year = 1991;日= 19,月= 11,年= 1986;日= 25,月= 2,年= 1956
  4. 下面显然不起作用,因为它只考虑一个搜索实例,可能有3个甚至10个:

    query.Where(o => o.Day == 3 && o.Month == 4 && o.Year == 1997);
    

    我试着研究Expression和ParameterExpression,但无法绕过它。

    [注] @Luaan是目前为止最接近的一个,加上“||”不会解决#1。

3 个答案:

答案 0 :(得分:5)

我要发布此信息并承担被投票的风险。但是,如果我没有错过这一点,您可以在||中使用where(或)条件:

query.Where(o => (o.Day == 12 && o.Month ==14 && o.Year == 1962) ||
                 (o.Day == 3 && o.Month == 4 && o.Year == 1977));

注意:这并不适合您列出的所有方案。只需添加更多条件,并小心使用括号将它们正确分开。

答案 1 :(得分:3)

为什么不加载日期,比如HashSet<DateTime>

   HashSet<DateTime> birthDays = new HashSet<DateTime>() {
     new DateTime(1962, 1, 12), 
     new DateTime(1977, 4, 3), 
     ...
   };

   ...

   var result = query
    .Where(o => birtDays.Contains(o));

或者我错过了什么?

答案 2 :(得分:0)

如果你需要动态构建它,使用几种扩展方法很容易。例如:

public static Expression<Func<T, bool>> False<T>(this IQueryable<T> @this)
  => _ => false;

public static Expression<Func<T, bool>> Or<T>
  (this Expression<Func<T, bool>> left, Expression<Func<T, bool>> right)
  =>
  Expression.Lambda<Func<T, bool>>
  (
    Expression.OrElse
    (
      left, 
      Expression.Invoke
      (
        right, 
        left.Parameters.Cast<Expression>()
      )
    ), 
    left.Parameters
  );
}

然后你可以这样做:

var predicate = query.False();

foreach (var date in filterDates)
{
  predicate = 
    predicate.Or(i => i.Day == date.Day && i.Month == date.Month && i.Year == date.Year);
}

query = query.Where(predicate);