Ce qui suit fonctionne très bien avec les types IEnumerable, mais est-il un moyen d'obtenir quelque chose comme ça en travaillant avec des types IQueryable contre une base de données sql?
Réponse
Trop de publicités?Si vous l'exprimer en where
clause, il peut simplement travailler hors de la boîte avec LINQ to SQL, si vous pouvez construire une expression adéquate.
Il peut y avoir une meilleure façon de faire cela dans les termes de l'expression des arbres - Marc Gravel pourriez bien être en mesure de l'améliorer - mais il vaut la peine d'essayer.
static class Ext
{
public static IQueryable<TSource> Between<TSource, TKey>
(this IQueryable<TSource> source,
Expression<Func<TSource, TKey>> keySelector,
TKey low, TKey high) where TKey : IComparable<TKey>
{
Expression key = Expression.Invoke(keySelector,
keySelector.Parameters.ToArray());
Expression lowerBound = Expression.GreaterThanOrEqual
(key, Expression.Constant(low));
Expression upperBound = Expression.LessThanOrEqual
(key, Expression.Constant(high));
Expression and = Expression.AndAlso(lowerBound, upperBound);
Expression<Func<TSource, bool>> lambda =
Expression.Lambda<Func<TSource, bool>>(and, keySelector.Parameters);
return source.Where(lambda);
}
}
Il va probablement dépendre du type si - en particulier, j'ai utilisé les opérateurs de comparaison plutôt que d' IComparable<T>
. Je crois que cela est plus susceptible d'être correctement traduit en SQL, mais vous pouvez le changer pour utiliser l' CompareTo
méthode si vous le souhaitez.
L'appeler comme ceci:
var query = db.People.Between(person => person.Age, 18, 21);