10

Ho il seguente codice LINQ:Impossibile convertire IQueryable <> per errore IOrderedQueryable

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

L'ultima riga (l'extra dove) mi sta dando l'errore:

Impossibile convertire implicitamente il tipo di sistema '. Linq.IQueryable 'to' System.Linq.IOrderedQueryable '.

Non sono sicuro di cosa significhi ...
Perché visualizzo questo errore?
E 'apparso una volta che ho aggiunto la clausola "orderby" alla query, prima che fosse compilata correttamente, quindi ho una specie di intuizione su cosa sta succedendo, ma non riesco a metterci un dito.

risposta

19

Prova dichiarando posts specificamente come IQueryable<Post> piuttosto che var (che prenderà il IOrderedQueryable<Post> (sarà ancora essere ordinato).

In alternativa, ri- strutturarlo quindi ordiniamo alla fine, permettendoci di (facoltativamente) di portare il nel mezzo:

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

(ovviamente, guardiamo finalQuery)

Il motivo è erroring è che attualmente si dispone (essenzialmente):

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

Entrambi hanno funzionato come un incantesimo, grazie! Cosa intendi ordinando alla fine piuttosto che nel mezzo? Non è il vero SQL generato ed eseguito dopo tutto questo, una volta che la query viene enumerata? Ho pensato che LINQ sarebbe stato abbastanza intelligente da "combinare" il DOVE ... –

+5

È l'OrderBy che cambia la firma ... rendendo l'OrderBy l'ultima cosa che applichiamo, abbiamo 'IQueryable ' dappertutto, che è più facile comporre. Come dici tu, il provider (EF, LINQ-to-SQL ecc.) Unirà tutto prima di eseguirlo comunque. –

+0

Aaaaah, quella spiegazione finale è SUPER chiara, gotcha. Grazie!! –

-5

Il risultato dell'espressione lambda di tipo IQueryable. Non consente il metodo di estensione Dove, quindi per usarlo prima è necessario convertirlo, ad esempio, in un elenco.

Si potrebbe fare questo usando

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

Hmmmmm, ma non sarebbe che prima eseguire una query che verrà portare tutti i record dal database e quindi filtrarli in base allo stato in ASP.Net? Preferisco che il DB elabori tutti i WHEREs, che è quello che pensavo fosse successo se avessi appena aggiunto la clausola .Where, dal momento che l'SQL sarebbe stato generato ed eseguito successivamente, quando i risultati sono enumerati. Nel tuo caso, ToList() non viene eseguito anche tu? –