10

Ich habe folgende LINQ-Code:Kann nicht IQueryable <> zu IOrderedQueryable Fehler konvertieren

var posts = (from p in db.Posts 
     .Include("Site") 
     .Include("PostStatus") 
     where p.Public == false 
     orderby p.PublicationTime 
     select p); 

     if (!chkShowIgnored.Checked) { 
      posts = posts.Where(p => p.PostStatus.Id != 90); 
     } 

Das letzte Zeile (das extra wo) wird mir den Fehler geben:

Kann Typ ‚System nicht implizit konvertieren. Linq.IQueryable 'zu' System.Linq.IOrderedQueryable '.

Ich bin mir nicht sicher, was das bedeutet ...
Warum erhalte ich diesen Fehler?
Es erschien, sobald ich die "Orderby" -Klausel zu der Abfrage hinzugefügt, bevor es kompiliert, so habe ich eine Art Ahnung von dem, was vor sich geht, aber ich kann nicht ganz meinen Finger hinein.

Antwort

19

Versuchen Sie es mit tun erklärt posts speziell als IQueryable<Post> statt var (die die IOrderedQueryable<Post> abholen (es wird noch) bestellt werden.

Alternativ re- Strukturieren Sie es so, dass wir am Ende bestellen, so dass wir (optional) die where in der Mitte einbringen können:

var posts = from p in db.Posts 
      .Include("Site") 
      .Include("PostStatus") 
      where p.Public == false 
      select p); 

if (!chkShowIgnored.Checked) { 
    posts = posts.Where(p => p.PostStatus.Id != 90); 
} 
var finalQuery = posts.OrderBy(p => p.PublicationTime); 

(natürlich schauen wir auf finalQuery)

Der Grund, es ist erroring ist, dass zur Zeit haben Sie (im Wesentlichen):

IOrderedQueryable<Post> posts = {snip}; 
... 
posts = {something (Where) that returns IQueryable<Post>} 
+0

Beide funktionierten wie ein Zauber, danke! Was meinst du, wir bestellen am Ende und nicht in der Mitte? Wird das eigentliche SQL nach all dem generiert und ausgeführt, sobald die Abfrage aufgelistet ist? Ich nahm an, LINQ wäre schlau genug, um die WHEREs zu "kombinieren" ... –

+5

Es ist die OrderBy, die die Signatur ändert ... indem wir die OrderBy zur letzten Sache machen, haben wir 'IQueryable ' überall, was einfacher ist komponieren. Wie Sie sagen, wird der Provider (EF, LINQ-to-SQL usw.) alles zusammenführen, bevor es trotzdem ausgeführt wird. –

+0

Aaaaah, diese letzte Erklärung ist SUPER klar, Gotcha. Vielen Dank!! –

-5

Das Ergebnis der Lambda-Expression ist vom Typ IQueryable. Die Erweiterungsmethode Where kann nicht verwendet werden. Um sie also zuerst zu verwenden, müssen Sie sie beispielsweise in eine Liste konvertieren.

Sie konnten dieses

posts = posts.ToList().Where(p => p.PostStatus.Id != 90); 
+4

Hmmmmm, würde aber nicht, dass zuerst eine Abfrage ausführen, das wird alle Datensätze aus der Datenbank holen und sie dann nach Status in ASP.Net filtern? Ich würde lieber die DB verarbeiten alle WHEREs, was ich dachte, passiert ist, wenn ich nur die. Where-Klausel hinzugefügt, da die SQL generiert und später ausgeführt würde, wenn die Ergebnisse aufgelistet wird. Führt ToList() in Ihrem Fall nicht zur Ausführung? –

Verwandte Themen