У меня есть один запрашиваемый , где я использовал различные операторы Where
и WhereBetween
, чтобы сузить коллекцию до определенного набора. Теперь Мне нужно добавить вид Where || WhereBetween
. Другими словами, я не могу просто связать их вместе, как до сих пор, потому что это будет работать как А. Итак, как я могу это сделать?
Я вижу две возможности:
- Создайте два запроса из того, что у меня есть, один с помощью
Where
, а другой с помощью WhereBetween
. А затем объединить их . Не знаете, возможно ли это вообще? Кроме того, хотя, не в моем конкретном случае, вы, скорее всего, получите дубликаты ...
- Каким-то образом объедините выражение
Where
и выражение, созданное в WhereBetween
, с каким-то видом Or.
Первое, как уже упоминалось, я не уверен, что это даже возможно. И если это так, я не уверен, что это хороший способ сделать это.
Второе, я могу видеть как вариант, но не совсем уверен во всех деталях. Ниже приведен метод 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? Я смотрю на Expression.OrElse
, используемый в методе WhereBetween
, и думаю, что это может быть то, что мне нужно, или, может быть, это Expression.Or
. Но я очень нестабилен в этом выражении, поэтому я не уверен, что выбрать здесь, или даже если я на правильном пути: p
Может ли кто-нибудь дать мне несколько советов здесь?