2009-11-13 29 views
10

Tengo el siguiente código de LINQ:no puede convertir IQueryable <> a un error 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); 
     } 

Esa última línea (el extra donde) me da el error:

No se puede convertir implícitamente el tipo de sistema'. Linq.IQueryable 'to' System.Linq.IOrderedQueryable '.

No estoy seguro de lo que esto significa ...
¿Por qué me sale este error?
Apareció una vez que agregué la cláusula "orderby" a la consulta, antes de que se compilara bien, así que tengo una corazonada de lo que está sucediendo, pero no puedo poner mi dedo en ello.

Respuesta

19

Trate declarar posts específicamente como IQueryable<Post> en lugar de var (que recoger el IOrderedQueryable<Post> (será todavía se ordenó).

Alternativamente, re estructurarlo así que ordenamos al final, lo que nos permite (opcionalmente) traer el where en el medio:

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

(obviamente, nos fijamos en finalQuery)

La razón de que se erroring es que actualmente tiene (esencialmente):

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

Ambos funcionaron como un encanto, ¡gracias! ¿A qué te refieres con que ordenamos al final en vez de en el medio? ¿No se genera y se ejecuta el SQL real después de todo esto, una vez que se enumera la consulta? Supuse que LINQ sería lo suficientemente inteligente como para "combinar" los WHEREs ... –

+5

Es el OrderBy el que cambia la firma ... al hacer el OrderBy lo último que aplicamos, tenemos 'IQueryable ' en todo momento, lo cual es más fácil Para componer. Como dices, el proveedor (EF, LINQ-to-SQL, etc.) fusionará todo antes de ejecutarlo de todos modos. –

+0

Aaaaah, esa explicación final es SUPER clara, gotcha. ¡¡Gracias!! –

-5

El resultado de la lambda expressionis de tipo IQueryable. No permite el método de extensión Dónde, así que para usarlo primero debe convertirlo a, por ejemplo, una lista.

Usted puede hacer esto utilizando

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

Hmmmmm, pero ¿no que primero ejecutar una consulta que va a traer todos los registros de la base de datos, y luego filtrarlos por estado en ASP.Net? Prefiero que el DB procese todos los WHERE, que es lo que pensé que pasó si acabo de agregar la cláusula .Where, ya que el SQL se generaría y se ejecutaría más tarde, cuando se enumeren los resultados. En su caso, ¿ToList() no causa que se ejecute también? –

Cuestiones relacionadas