2009-09-19 11 views
33

Die folgenden funktioniert gut mit IEnumerable Typen, aber gibt es eine Möglichkeit, etwas wie das Arbeiten mit IQueryable-Typen gegen eine SQL-Datenbank zu bekommen?LINQ zwischen Operator

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

Antwort

44

Wenn Sie es als where Klausel ausdrücken kann nur mit LINQ to SQL aus der Box arbeiten, wenn Sie einen entsprechenden Ausdruck konstruieren können.

Vielleicht gibt es einen besseren Weg, dies in Bezug auf die Ausdrucksbäume zu tun - Marc Gravell kann es vielleicht verbessern - aber es ist einen Versuch wert.

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

Es wird wahrscheinlich obwohl beteiligt von der Art abhängen - insbesondere, ich habe die Vergleichsoperatoren statt IComparable<T> verwendet. Ich vermute, dass dies mit größerer Wahrscheinlichkeit korrekt in SQL übersetzt wird, aber Sie könnten es ändern, um die Methode CompareTo zu verwenden, wenn Sie möchten.

es wie folgt aufrufen:

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

Nizza. Dies hat mich auch dazu gebracht, Linq Ausdrücke ein wenig mehr zu verstehen. – Dykam

+0

Jon, Entschuldigung, ich habe das nicht akzeptiert. Seit ein paar Tagen unter dem Wetter. Frage: Sie schreiben über die Verwendung von Vergleichsoperatoren anstelle von IComparable . Wie würde das aussehen? Wie würde das als IEnumerable aussehen? Ich muss damit spielen und hoffe, das heute zu tun. Vielen Dank! – andleer

+0

Mit 'IComparable ' benötigen Sie Ausdrucksbäume, um CompareTo zweimal aufzurufen. Alles machbar, aber ein bisschen Schmerz. Nicht sicher, was du meinst über "Wie würde das alles aussehen als 'IEnumerable '? " - Können Sie das ausarbeiten? –

Verwandte Themen