28 votes

LINQ entre l'opérateur

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?

39voto

Jon Skeet Points 692016

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);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X