C# Lambda - Where - 相同条件的多个表达式
C# Lambda - Where - Mulitple expressions of the same criteria
假设 - 一家派对商店想要 select 人们根据他们数据库中的标准。
数据库名称"BirthDays" 字段:日、月、年
"where" 需要动态考虑搜索实例的每个考虑因素:
- 日 = 12,月 = 1,年 = 1962
- 日 = 3,月 = 4,年 = 1977 ;日 = 13,月 = 4,年 = 1977
- 日=20,月=8,年=1941;日 = 9,月 = 1,年 = 1991 ;日 = 19,月 = 11,年 = 1986 ;日 = 25,月 = 2,年 = 1956
下面显然行不通,因为它只考虑一个搜索实例,而可能有 3 个甚至 10 个:
query.Where(o => o.Day == 3 && o.Month == 4 && o.Year == 1997);
我尝试查看 Expression 和 ParameterExpression,但无法理解它。
[注意]
@Luaan 是目前为止最接近的,加了“||”不会解决#1。
我要 post 并承担被否决的风险。但是,如果我没有错过重点,您可以在 where
:
中使用 ||
(或)条件
query.Where(o => (o.Day == 12 && o.Month ==14 && o.Year == 1962) ||
(o.Day == 3 && o.Month == 4 && o.Year == 1977));
注意:这并不适合您列出的所有场景。只需附加更多条件,并注意使用括号将它们正确分隔。
为什么不加载日期,比如 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));
还是我漏掉了什么?
如果您需要动态构建它,使用几个扩展方法非常容易。例如:
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);
假设 - 一家派对商店想要 select 人们根据他们数据库中的标准。
数据库名称"BirthDays" 字段:日、月、年
"where" 需要动态考虑搜索实例的每个考虑因素:
- 日 = 12,月 = 1,年 = 1962
- 日 = 3,月 = 4,年 = 1977 ;日 = 13,月 = 4,年 = 1977
- 日=20,月=8,年=1941;日 = 9,月 = 1,年 = 1991 ;日 = 19,月 = 11,年 = 1986 ;日 = 25,月 = 2,年 = 1956
下面显然行不通,因为它只考虑一个搜索实例,而可能有 3 个甚至 10 个:
query.Where(o => o.Day == 3 && o.Month == 4 && o.Year == 1997);
我尝试查看 Expression 和 ParameterExpression,但无法理解它。
[注意] @Luaan 是目前为止最接近的,加了“||”不会解决#1。
我要 post 并承担被否决的风险。但是,如果我没有错过重点,您可以在 where
:
||
(或)条件
query.Where(o => (o.Day == 12 && o.Month ==14 && o.Year == 1962) ||
(o.Day == 3 && o.Month == 4 && o.Year == 1977));
注意:这并不适合您列出的所有场景。只需附加更多条件,并注意使用括号将它们正确分隔。
为什么不加载日期,比如 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));
还是我漏掉了什么?
如果您需要动态构建它,使用几个扩展方法非常容易。例如:
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);