2013-04-24 16 views
6

Zur Zeit habe ich diese, die 500 Zeilen automatisch erfolgt:Zugabe Bedingtes .Nehmen()

var orderQuery = subsetTable.Where(pred).OrderByDescending(o => o.CreationDate).Take(500); 

Ich möchte den Take() bedingt, so etwas machen:

var orderQuery = subsetTable.Where(pred).OrderByDescending(o => o.CreationDate); 
if (condition) 
    orderQuery = orderQuery.Take(500); 

Ist das möglich?

Edit:
Der Compiler sagt

"Kann nicht implizit Typ umwandeln 'System.Linq.IQueryable' zu 'System.Linq.IOrderedQueryable'."

+0

Was tat zu konvertieren Ihr Compiler sagen Ihnen? –

Antwort

8

Add "AsQueryable" die Typen zu machen, in einer Reihe aufstellen:

var orderQuery = subsetTable.Where(pred).OrderByDescending(o => o.CreationDate).AsQueryable(); 
if (condition) 
    orderQuery = orderQuery.Take(500); 
+0

Ich benutzte dies, um die Verwendung von Var. Danke an alle. – chrismat

6

Ist das möglich?

Ja. Ihr Code sollte fast wie geschrieben funktionieren. Sie müssen nur die var beseitigen. Angenommen, Ihr Typ ist Order. Sie würden verwenden:

IQueryable<Order> orderQuery = subsetTable.Where(pred).OrderByDescending(o => o.CreationDate); 
if (condition) 
    orderQuery = orderQuery.Take(500); 
+0

Eigentlich glaube ich nicht, dass es wegen der 'var' auf 'IorderedEnumerable <>' in der ersten Anweisung und 'Take' nach' IEnumerable <>' in der zweiten folgen würde. –

+1

@AnthonyPegram True - behoben. –

10

In Linq-to-Objekte, die var zu IOrderedEnumerable<T> schließen wird, wo T die Art des Objekts ist. Die Take() ergibt eine IEnumerable<T>, so dass Ihre Codezeile dort nicht erlaubt ist. (IOrderedEnumerable ist genauer spezifiziert als IEnumerable, Sie müssen Ihre Abfrage in einer weniger spezifizierten Weise eingeben.) Und, wie die Kommentare darauf hinweisen, gilt das Gleiche für Anbieter, die in Bezug auf IQueryable<T> handeln, die sich selbst als a ausdrücken kann weniger spezifiziert IEnumerable<T>.

Um dies zu ermöglichen, geben Sie Ihre Abfrage explizit in den kleineren angegebenen Typ ein, IEnumerable<T> oder IQueryable<T>, und dann können Sie Ihre bedingte Take anwenden.

IEnumerable<YourType> orderedQuery = ... 
if (condition) 
    orderedQuery = orderedQuery.Take(n); 
+1

+1 Und in LINQ zu SQL/entities/NHibernate ersetzen "IEnumerable" durch "IQueryable" und das gleiche ist wahr. –

-1

Was ich tue, ist am Ende hinzuzufügen, Sortierung, um zu vermeiden, sie

var orderQuery = subsetTable.Where(pred); 

if (condition) 
    orderQuery = orderQuery.Take(500); 

orderQuery = orderQuery.OrderByDescending(o => o.CreationDate); 
+3

Dies ändert das Verhalten, da Sie nur die ersten 500 Elemente sortieren und nicht die ersten 500 sortierten Elemente. –

+0

Nein, das '.Take (500)' wird angewendet, wenn Sie die Abfrage ausführen. In '.List();' zum Beispiel –

+0

Ja - die Take wird ausgeführt, wenn Sie abfragen, aber die Take wird interpretiert, um die Ergebnisse zu nehmen, dann sortieren, wo das Original sort war, dann nehmen (auf dem Server). –