2009-09-19 13 views
33

Poniższe działa dobrze z typami IEnumerable, ale czy istnieje sposób, aby coś takiego pracy z typami IQueryable przeciwko bazy danych sql?LINQ Między operatorem

class Program 
{ 
    static void Main(string[] args) 
    { 
     var items = new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, }; 

     foreach (var item in items.Where(i => i.Between(2, 6))) 
      Console.WriteLine(item); 
    } 
} 

static class Ext 
{ 
    public static bool Between<T>(this T source, T low, T high) where T : IComparable 
    { 
     return source.CompareTo(low) >= 0 && source.CompareTo(high) <= 0; 
    } 
} 

Odpowiedz

44

Jeśli wyrazić go jako where klauzuli to może prostu pracować po wyjęciu z pudełka z LINQ to SQL, czy można skonstruować odpowiedni wyraz.

Może być lepszy sposób robienia tego w kategoriach drzewek ekspresji - Marc Gravell może być w stanie to poprawić - ale warto spróbować.

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

To będzie prawdopodobnie zależeć od rodzaju zaangażowanych choć - w szczególności Użyłem operatorów porównania zamiast IComparable<T>. Podejrzewam, że jest to bardziej prawdopodobne, że zostanie poprawnie przetłumaczone na SQL, ale możesz go zmienić, aby użyć metody CompareTo, jeśli chcesz.

Wywołuje to tak:

var query = db.People.Between(person => person.Age, 18, 21); 
+0

Nicea. Dzięki temu mogłem zrozumieć nieco wyrażenia Linqa. – Dykam

+0

Jon, Niestety, nie zaakceptowałem tego. Byłeś pod wpływem pogody przez kilka dni. Pytanie: piszesz o użyciu operatorów porównania zamiast IComparable . Jakby to wyglądało? Co by to wyglądało jak IEnumerable ? Muszę się z tym bawić i mam nadzieję, że zrobię to dzisiaj. Dzięki wielkie! – andleer

+0

Używając 'IComparable ' potrzebujesz drzewek wyrażeń do wywołania CompareTo dwa razy. Wszystko wykonalne, ale trochę uciążliwe. Nie wiesz, co masz na myśli, mówiąc: "Co by to mogło wyglądać jako" IEnumerable "?" - czy możesz rozwinąć? –

Powiązane problemy