Expresión fluida y de consulta: ¿hay algún beneficio de uno sobre otro?

255

LINQ es una de las mayores mejoras a .NET desde los genéricos y me ahorra toneladas de tiempo y líneas de código. Sin embargo, la sintaxis fluida parece ser mucho más natural para mí que la sintaxis de expresión de consulta.

var title = entries.Where(e => e.Approved)
    .OrderBy(e => e.Rating).Select(e => e.Title)
    .FirstOrDefault();

var query = (from e in entries
             where e.Approved
             orderby e.Rating
             select e.Title).FirstOrDefault();

¿Hay alguna diferencia entre los dos o hay algún beneficio particular de uno sobre otro?

JarrettV
fuente
1
Para consultas complejas, encuentro que la sintaxis lambda es más comprensible / legible, pero la sintaxis de consulta simplemente es más bonita.
nawfal

Respuestas:

255

Ninguno de los dos es mejor: atienden diferentes necesidades. La sintaxis de la consulta tiene su propio significado cuando desea aprovechar múltiples variables de rango . Esto sucede en tres situaciones:

  • Cuando se usa la palabra clave let
  • Cuando tienes múltiples generadores ( de cláusulas)
  • Al hacer uniones

Aquí hay un ejemplo (de las muestras de LINQPad):

string[] fullNames = { "Anne Williams", "John Fred Smith", "Sue Green" };

var query =
  from fullName in fullNames
  from name in fullName.Split()
  orderby fullName, name
  select name + " came from " + fullName;

Ahora compare esto con lo mismo en la sintaxis del método:

var query = fullNames
  .SelectMany (fName => fName.Split().Select (name => new { name, fName } ))
  .OrderBy (x => x.fName)
  .ThenBy  (x => x.name)
  .Select  (x => x.name + " came from " + x.fName);

La sintaxis del método, por otro lado, expone la gama completa de operadores de consulta y es más concisa con consultas simples. Puede obtener lo mejor de ambos mundos combinando la sintaxis de consulta y método. Esto a menudo se realiza en consultas LINQ to SQL:

var query =
  from c in db.Customers
  let totalSpend = c.Purchases.Sum (p => p.Price)    // Method syntax here
  where totalSpend > 1000
  from p in c.Purchases
  select new { p.Description, totalSpend, c.Address.State };
Joe Albahari
fuente
2
Buena respuesta. ¿Me puede contar un poco más sobre lo que está haciendo ".Select (name => new {name, fName})"?
Quillbreaker
12
Selecciona la palabra individual (anne, williams, john, etc.) junto con el nombre completo en un tipo anónimo. Esto le permite "llevar" el nombre completo original para que tenga acceso tanto al nombre completo como a la palabra individual en el resto de la consulta.
Joe Albahari
58

Prefiero usar este último (a veces llamado "sintaxis de comprensión de consultas") cuando puedo escribir la expresión completa de esa manera.

var titlesQuery = from e in entries
                  where e.Approved
                  orderby e.Rating
                  select e.Titles;

var title = titlesQuery.FirstOrDefault();

Tan pronto como tengo que agregar (paréntesis) y .MethodCalls(), cambio.

Cuando uso el primero, generalmente pongo una cláusula por línea, como esta:

var title = entries
    .Where (e => e.Approved)
    .OrderBy (e => e.Rating)
    .Select (e => e.Title)
    .FirstOrDefault();

Me parece un poco más fácil de leer.

Jay Bazuzi
fuente
29

Cada estilo tiene sus pros y sus contras. La sintaxis de consulta es más agradable cuando se trata de uniones y tiene la útil palabra clave let que facilita la creación de variables temporales dentro de una consulta.

La sintaxis fluida, por otro lado, tiene muchos más métodos y operaciones que no están expuestos a través de la sintaxis de consulta. Además, dado que son solo métodos de extensión, puede escribir los suyos.

He descubierto que cada vez que comienzo a escribir una declaración LINQ usando la sintaxis de consulta, termino teniendo que ponerla entre paréntesis y recurrir al uso de métodos de extensión LINQ fluidos. La sintaxis de consulta simplemente no tiene suficientes características para usar por sí misma.

James Newton-King
fuente
"Ya que son solo métodos de extensión, puedes escribir el tuyo". - ¿Te encontrarás con este problema? stackoverflow.com/a/3850254/1175496
The Red Pea
20

En VB.NET, prefiero la sintaxis de consulta.

Odio repetir la fea Functionpalabra clave:

Dim fullNames = { "Anne Williams", "John Fred Smith", "Sue Green" };
Dim query =
     fullNames.SelectMany(Function(fName) fName.Split().
     Select(Function(Name) New With {Name, fName})).
     OrderBy(Function(x) x.fName).
     ThenBy(Function(x) x.Name).
     Select(Function(x) x.Name & " came from " & x.fName)

Esta consulta ordenada es mucho más legible y mantenible en mi opinión:

query = From fullName In fullNames
        From name In fullName.Split()
        Order By fullName, name
        Select name & " came from " & fullName

La sintaxis de consulta de VB.NET también es más potente y menos detallada que en C #: https://stackoverflow.com/a/6515130/284240

Por ejemplo, esta consulta LINQ to DataSet (Objetos)

VB.NET:

Dim first10Rows = From r In dataTable1 Take 10

C#:

var first10Rows = (from r in dataTable1.AsEnumerable() 
                   select r)
                   .Take(10);
Tim Schmelter
fuente
99
Mis condolencias por los desarrolladores de VB que no pueden usar el estilo de consulta.
nawfal
1
Su último ejemplo de C # es demasiado simplista para ser valioso: simplemente escribiría `dataTable1.AsEnumerable (). Take (10);
Emyr
@Emyr: mi último párrafo que comienza con "La sintaxis de consulta de VB.NET también es más potente y menos detallada que en C #" es simplemente comparar la sintaxis de consulta de VB.NET con C #, está utilizando la sintaxis de método.
Tim Schmelter
15

No obtengo la sintaxis de consulta en absoluto. Simplemente no hay razón para ello en mi mente. let se puede lograr con .Select y tipos anónimos. Simplemente creo que las cosas se ven mucho más organizadas con la "puntuación" allí.

Cazador de instancias
fuente
99
Las combinaciones múltiples pueden volverse bastante laboriosas con bastante rapidez con la sintaxis fluida. Sin embargo, generalmente uso fluidez, a menos que haya uniones involucradas.
Roman Starkov
1
@Instance Hunter: lo mismo aquí. Me tomó bastante tiempo comenzar a comprender la idea de una sintaxis fluida. En combinación con las poderosas funciones enumerables y la idea de funciones "puras", ahora realmente lo disfruto, y antes las situaciones difíciles que no tenían una buena representación de código. Para ye-ole-SQL-parte del cerebro, sigue siendo una bendición tener sintaxis de consulta.
Xan-Kun Clark-Davis
13

La interfaz fluida si solo hay un lugar. Si necesito una selección o un pedido, generalmente uso la sintaxis de consulta.

James Curran
fuente
8

La sintaxis fluida parece más poderosa, también debería funcionar mejor para organizar el código en pequeños métodos reutilizables.

Kozyarchuk
fuente
5

Sé que esta pregunta está etiquetada con C #, pero la sintaxis fluida es dolorosamente detallada con VB.NET.

Larsenal
fuente
4

Realmente me gusta la sintaxis Fluent y trato de usarla donde puedo, pero en ciertos casos, por ejemplo, donde uso combinaciones, generalmente prefiero la sintaxis de Consulta, en esos casos me resulta más fácil de leer, y creo que algunas personas son más familiares para la sintaxis de consultas (tipo SQL) que las lambdas.

CMS
fuente
4

Si bien entiendo y me gusta el formato fluido, me he quedado en Query por el momento por razones de legibilidad. Las personas que acaban de ser introducidas en LINQ encontrarán la consulta mucho más cómoda de leer.

LizB
fuente
4

Prefiero la sintaxis de consulta ya que provengo de la programación web tradicional que usa SQL. Es mucho más fácil para mí entenderlo. Sin embargo, creo que comenzaré a utilizar .Where (lambda) ya que definitivamente es mucho más corto.

Steve Tranby
fuente
4

He estado usando Linq durante aproximadamente 6 meses. Cuando comencé a usarlo, preferí la sintaxis de consulta, ya que es muy similar a T-SQL.

Sin embargo, poco a poco me voy acercando al primero, ya que es fácil escribir fragmentos de código reutilizables como métodos de extensión y simplemente encadenarlos. Aunque encuentro que poner cada cláusula en su propia línea ayuda mucho con la legibilidad.

Antony Scott
fuente
3

Acabo de establecer los estándares de nuestra empresa y aplicamos el uso de los métodos de Extensión. Creo que es una buena idea elegir uno sobre el otro y no mezclarlos en el código. Los métodos de extensión se leen más como el otro código.

La sintaxis de comprensión no tiene todos los operadores y usa paréntesis alrededor de la consulta y agrega métodos de extensión después de todo, solo me ruega que use métodos de extensión desde el principio.

Pero en su mayor parte es solo preferencia personal con algunas excepciones.

Rodi
fuente
3
No impondré preferencias personales ... Pero ese soy yo.
Memet Olsen