【发布时间】:2010-10-08 20:28:50
【问题描述】:
我有一个可查询的,我使用了各种 Where 和 WhereBetween 语句将集合缩小到某个集合。现在我需要添加一种Where || WhereBetween。换句话说,我不能像到目前为止那样将它们链接在一起,因为这将作为 And 起作用。那么,我该怎么做呢?
我看到了两种可能性:
-
从我拥有的一个中创建两个可查询项,一个使用
Where,一个使用WhereBetween。 然后将它们连接起来。不知道这是否可能?此外,虽然不是在我的特定情况下,但您很可能最终会出现重复... - 以某种方式将
Where表达式和WhereBetween中创建的表达式与某种或合并。
第一个,如上所述,我不确定是否可能。如果是这样,我不太确定这是一个好方法。
第二个,我可以将其视为一个选项,但不能完全确定所有细节。下面是我另一个问题中的WhereBetween 方法,我现在使用它并且效果很好:
public static IQueryable<TSource> WhereBetween<TSource, TValue>(
this IQueryable<TSource> source,
Expression<Func<TSource, TValue>> selector,
IEnumerable<Range<TValue>> ranges)
{
var param = Expression.Parameter(typeof(TSource), "x");
var member = Expression.Invoke(selector, param);
Expression body = null;
foreach (var range in ranges)
{
var filter = Expression.AndAlso(
Expression.GreaterThanOrEqual(member,
Expression.Constant(range.A, typeof(TValue))),
Expression.LessThanOrEqual(member,
Expression.Constant(range.B, typeof(TValue))));
body = body == null ? filter : Expression.OrElse(body, filter);
}
return body == null ? source : source.Where(
Expression.Lambda<Func<TSource, bool>>(body, param));
}
我在想我可以将它的表达式构建部分提取到一个新方法中。可能是这样的:
public static IQueryable<TSource> WhereBetween<TSource, TValue>(
this IQueryable<TSource> source,
Expression<Func<TSource, TValue>> selector,
IEnumerable<Range<TValue>> ranges)
{
return source.Where(WhereBetween(selector, ranges));
}
public static Expression<Func<TSource, bool>> WhereBetween<TSource, TValue>(
Expression<Func<TSource, TValue>> selector,
IEnumerable<Range<TValue>> ranges)
{
var param = Expression.Parameter(typeof(TSource), "x");
var member = Expression.Invoke(selector, param);
Expression body = null;
foreach (var range in ranges)
{
var filter = Expression.AndAlso(
Expression.GreaterThanOrEqual(member,
Expression.Constant(range.A, typeof(TValue))),
Expression.LessThanOrEqual(member,
Expression.Constant(range.B, typeof(TValue))));
body = body == null ? filter : Expression.OrElse(body, filter);
}
return body == null
? ø => true
: Expression.Lambda<Func<TSource, bool>>(body, param);
}
然后我可以使用这个新方法来获取表达式而不是可查询的。所以,假设我有WhereBetween(ø => ø.Id, someRange),例如ø => ø.SomeValue == null。我怎样才能将这两者与 Or 结合起来?我正在查看WhereBetween 方法中使用的Expression.OrElse,我认为这可能是我需要的,或者这可能是Expression.Or。但是我对这个表达的东西很不稳定,所以我不确定在这里选择什么,或者即使我在正确的轨道上:p
有人可以在这里给我一些指示吗?
【问题讨论】:
标签: c# linq-to-sql lambda expression-trees iqueryable