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