Ho uno interrogabile dove ho utilizzato varie istruzioni Where
e WhereBetween
per restringere la raccolta a un determinato set. Ora Devo aggiungere una specie di Where || WhereBetween
. In altre parole, non posso semplicemente unirle insieme come ho fatto finora, perché funzionerà come un E. Quindi, come posso fare questo?C#, Linq2Sql: è possibile concatenare due queryable in uno?
Vedo due possibilità:
- Creare due queryables da quello che ho, uno con il
Where
, e uno conWhereBetween
. E quindi concatenarli. Non so se questo è anche possibile? Inoltre, anche se non nel mio caso particolare, molto probabilmente finirai con duplicati ... - In qualche modo unire l'espressione
Where
e l'espressione creata nelloWhereBetween
con una sorta di Or.
Il primo, come detto, io non sono sicuro è ancora possibile. E se lo fosse, non sono così sicuro che sia un buon modo per farlo.
Il secondo, posso vedere come opzione, ma non completamente sicuro di tutti i dettagli. Di seguito è riportato il metodo WhereBetween
dalla mia altra questione, che ora io uso e funziona benissimo:
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));
}
Sto pensando che avrei potuto forse estrarre la porzione di edificio espressione di esso in un nuovo metodo. Forse così:
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);
}
Potrei quindi utilizzare questo nuovo metodo per ottenere l'espressione anziché l'interrogabile. Quindi, diciamo che ho il WhereBetween(ø => ø.Id, someRange)
e per esempio ø => ø.SomeValue == null
. Come posso combinare questi due con Or? Sto guardando il Expression.OrElse
utilizzato nel metodo WhereBetween
e penso che potrebbe essere quello che mi serve, o forse questo il Expression.Or
. Ma sono molto instabile su questa espressione, quindi non sono sicuro di cosa scegliere qui, o anche se sono sulla buona strada: p
Qualcuno potrebbe darmi qualche suggerimento qui?
Quella cosa fila potrebbe essere niente di buono?(Qualsiasi stringa che sia, ovviamente) – Svish
Pensando alle prestazioni sql e simili, è più efficiente con un 'UNION' o un' OR' nella 'WHERE'clause? – Svish
Molto bello. Questa domanda continua a venire (in variazioni) e il tuo OrElse potrebbe essere solo la pallottola magica che li risolve tutti. –