Actualización: Ha corregido su título, por lo tanto, ignórelo.
El título de su pregunta no tiene nada que ver con los ejemplos de su código. Su pregunta implica que una sintaxis es IEnumerable y la otra es IQueryable, pero esto es incorrecto. En sus muestras, si db.Surveys
es un IQueryable, entonces ambos sus muestras están usando IQueryable. Trataré de responder ambas preguntas.
Los dos ejemplos de código son simplemente formas diferentes de escribir las mismas consultas LINQ (suponiendo que estén bien escritas). El código en la muestra 1 es solo una abreviatura del código en la muestra 2. El compilador trata el código en ambas muestras de la misma manera. Piense en la forma en que el compilador de C# tratará int?
de la misma manera que Nullable<System.Int32>
. Los lenguajes C# y VB.Net proporcionan esta sintaxis de consulta abreviada. Es posible que otros idiomas no tengan esta sintaxis y deberá usar la sintaxis de la muestra 2. De hecho, es posible que otros lenguajes ni siquiera admitan métodos de extensión o expresiones lambda, y usted tendría que usar una sintaxis más fea aún.
Actualización:
Para tomar el ejemplo de Sander aún más, al escribir esto (la sintaxis de la comprensión de la consulta):
var surveyNames = from s in db.Surveys select s.Name
Usted piensa el compilador vueltas que forma abreviada en este (métodos de extensión y expresión lambda):
IQueryable<string> surveryNames = db.Surveys.Select(s => s.Name);
Pero en realidad los métodos de extensión y las expresiones lambda son taquigrafía.Los compiladores emite algo como esto (no exactamente, pero sólo para dar una idea):
Expression<Func<Survey, string>> selector = delegate(Survey s) { return s.Name; };
IQueryable<string> surveryNames = Queryable.Select(db.Surveys, selector);
Tenga en cuenta que Select()
es sólo un método estático de la clase Queryable
. Si su lenguaje .NET no admite sintaxis de consulta, lambdas o métodos de extensión, de alguna manera tendrá que escribir el código usted mismo.
¿Cuáles son los beneficios de usar un estilo sobre el otro?
Para pequeñas consultas, métodos de extensión pueden ser más compacta:
var items = source.Where(s => s > 5);
Además, la sintaxis método de extensión puede ser más flexible, tal como condicional donde cláusulas:
var items = source.Where(s => s > 5);
if(smallerThanThen)
items = items.Where(s => s < 10);
if(even)
items = items.Where(s => (s % 2) == 0);
return items.OrderBy(s => s);
Además , varios métodos solo están disponibles a través de la sintaxis del método de extensión (Count(), Aggregate(), Take(), Skip(), ToList(), ToArray(), etc.), así que si uso uno de estos, I ' Normalmente escribiré toda la consulta en esta sintaxis para evitar mezclar b otras sintaxis
var floridaCount = source.Count(s => s.State == "FL");
var items = source
.Where(s => s > 5)
.Skip(5)
.Take(3)
.ToList();
Por otra parte, cuando una consulta se hace más grande y más compleja, la sintaxis comprensión consulta puede ser más claro, sobre todo una vez que comience complicando con unos pocos let
, group
, join
, etc.
En el Fin usualmente usaré el que funcione mejor para cada consulta específica.
Actualización: usted fijó su título, así que ignore el resto ...
Ahora, sobre su título: Con respecto a LINQ, IEnumerable y IQueryable son muy similares. Ambos tienen prácticamente los mismos métodos de extensión (Seleccionar, Dónde, Contar, etc.), siendo la principal (¿única?) Diferencia que IEnumerable toma Func<TIn,TOut>
como parámetros e IQueryable toma Expression<Func<TIn,TOut>>
como parámetros. Expresas ambos de la misma manera (generalmente expresiones lamba), pero internamente son completamente diferentes.
IEnumerable es la puerta de entrada a LINQ to Objects. Se pueden invocar los métodos de extensión LINQ to Objects en cualquier IEnumerable (matrices, listas, cualquier cosa que pueda iterar con foreach
) y el Func<TIn,TOut>
se convierte a IL en tiempo de compilación y se ejecuta como un código de método normal en tiempo de ejecución. Tenga en cuenta que algunos otros proveedores de LINQ utilizan IEnumerable y, de hecho, están utilizando LINQ to Objects tras bastidores (LINQ to XML, LINQ to DataSet).
IQueryable es utilizado por LINQ to SQL, LINQ to Entities y otros proveedores de LINQ que necesitan examinar su consulta y traducirla en lugar de ejecutar su código directamente. Las consultas IQueryable y sus Expression<Func<TIn,TOut>>
s no se compilan en IL en el momento de la compilación. En su lugar, se crea un árbol de expresión que se puede examinar en tiempo de ejecución. Esto permite que las declaraciones se traduzcan a otros lenguajes de consulta (por ejemplo, T-SQL). Un árbol de expresiones se puede compilar en un Func < TIn, TOut > en tiempo de ejecución y se puede ejecutar si se desea.
Encontrará un ejemplo que ilustra la diferencia en this question donde OP desea hacer parte de una consulta LINQ to SQL en SQL Server, llevar los objetos al código administrado y hacer el resto de la consulta en LINQ to Objects . Para lograr esto, todo lo que tiene que hacer es convertir el IQueryable en un IEnumerable donde quiera que ocurra el cambio.
sus vale la pena mencionar sus muestras no son idénticos ... –
También el .ToList() a las fuerzas finales de ejecución muy diferente. Déjelo apagado para que sea equivalente. La primera x es de tipo IQueryable y la segunda es IList . –