У меня есть один запрашиваемый, где я использовал различные Where
и WhereBetween
заявления, чтобы сузить коллекцию до определенного набора. Теперь Мне нужно добавить вид Where || WhereBetween
. Другими словами, я не могу просто связать их вместе, как я до сих пор, потому что это будет работать как И. Итак, как я могу это сделать?C#, Linq2Sql: Можно ли объединить два запроса в один?
Я вижу две возможности:
- Создание двух queryables из одного у меня есть, один с помощью
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? Я смотрю на Expression.OrElse
, используемый в методе WhereBetween
, и я думаю, что это может быть то, что мне нужно, или, может быть, это Expression.Or
. Но я очень неустойчив в этом выражении, поэтому я не уверен, что выбрать здесь, или даже если я нахожусь на правильном пути: p
Может ли кто-нибудь дать мне несколько указателей здесь?
Эта строка вещь может быть что угодно, не так ли?(Любая строка, которая, конечно) – Svish
Думая о производительности sql и т. Д., Эффективнее ли это с UNION или OR в 'WHERE'clause? – Svish
Очень приятно. Этот вопрос продолжает расти (в вариациях), и ваш OrElse просто может быть волшебной пулей, которая решает их всех. –