2009-03-10 18 views
54

Estoy empezando a utilizar LINQ en general (hasta el momento en XML y toSQL). He visto que a veces hay dos o más formas de lograr los mismos resultados. Tome este ejemplo sencillo, por lo que yo entiendo ambos devuelven exactamente lo mismo:LINQ: Notación de puntos frente a Expresión de consulta

SomeDataContext dc = new SomeDataContext(); 

var queue = from q in dc.SomeTable 
     where q.SomeDate <= DateTime.Now && q.Locked != true 
     orderby (q.Priority, q.TimeCreated) 
     select q; 

var queue2 = dc.SomeTable 
     .Where(q => q.SomeDate <= DateTime.Now && q.Locked != true) 
     .OrderBy(q => q.Priority) 
     .ThenBy(q => q.TimeCreated); 

Además de cualquier error que pueda haber hecho en la sintaxis o un parámetro que falta o la diferencia, la idea es que hay dos maneras de expresar lo mismo; Entiendo que el primer método tiene algunas limitaciones y que la "notación de puntos" es más completa, pero además de eso, ¿hay alguna otra ventaja?

+0

Gracias a todos por las respuestas. Por desgracia, solo puedo marcar uno como la respuesta correcta. Pero aprecio todos los comentarios. –

+1

Duplicado: http://stackoverflow.com/questions/214500/which-linq-syntax-do-you-prefer-fluent-or-query-expression – Mikhail

Respuesta

48

La notación "punto" se suele llamar la sintaxis lambda. La primera notación tiene varios nombres, pero generalmente la llamo sintaxis de consulta.

Trabajo en un equipo de 10 desarrolladores y discutimos largamente sobre lo que deberíamos usar como estándar. En general, los desarrolladores más experimentados (con LINQ) migran hacia la sintaxis de Lambda, pero hay excepciones significativas.

Lambda es más conciso pero realizar múltiples combinaciones de tablas es una pesadilla. Las uniones son mucho más limpias con la sintaxis de consulta. La otra cara de la moneda es que hay varias operaciones LINQ que solo existen dentro de la sintaxis Lambda: Single(), First(), Count() etc.

Así que usa lo que te sientas más cómodo y date cuenta de que ganas experiencia, tu preferencia probablemente cambie. Hay un gran valor para poder leer ambos y ciertamente habrá situaciones en las que tendrá que usar un poco de ambos. Otras situaciones se prestan a un estilo sobre el otro. Al final, todo se traduce al mismo código ejecutable.

+1

5 años después y la sintaxis lambda con cadenas de métodos ahora se conoce comúnmente como [Interfaz fluida] (http://en.wikipedia.org/wiki/Fluent_interface). – Nick

8

Bueno, la notación 'punto' puede ser mucho más corta. Tome:

var result = from p in dc.Products 
      where p.Id > 5 
      select p; 

o:

var result = dc.Products.Where(p => p.Id > 5); 

prefiero esta última ya que es mucho más corto y más fácil de leer.

+0

Cuando uso LINQ to SQL prefiero el primero porque está más cerca de T- SQL (que es útil cuando se escriben consultas DB) y el último para otras consultas LINQ (como LINQ a XML). – RobS

+0

Sí, tienes un punto allí. Con linq2sql a menudo uso la primera versión, por la misma razón que mencionas. Aunque también debo admitir que para consultas muy simples como la anterior, a menudo utilizo la segunda versión corta, simplemente porque soy flojo :-) – Razzie

+0

No siempre es más corto, y a veces es más difícil de leer, pero tienes una señalar que puede ser un poco más corto. –

2

Recopilan el mismo código, o más bien el primero se traduce primero al segundo y luego se compila.

Tiene razón en que la primera versión es más limpia pero más limitada. En la segunda se puede utilizar, por ejemplo, los delegados ya existentes, por ejemplo .:

Func<int, bool> isEven = i => i%2 == 0; 
Enumerable.Range(10).Where(isEven).ToList().ForEach(Console.WriteLine); 
+0

No del todo cierto. Puede utilizar aún usar un delegado existente, por ejemplo: var result = from s en la lista donde isEven.Invoke (s.Length) select s; – Razzie

+0

sí, pero hablando de estilo *. Invocar es simplemente feo :) – user76035

+1

no necesita usar Invocar, esto funciona bien: var resultado = desde i en las entradas donde isEven (i) seleccione i; – theburningmonk

27

Uso la sintaxis que sea más legible para mi consulta, caso por caso.

Siempre que sea posible, trato de evitar mezclar y combinar los dos, aunque a veces que está bien (si se trata de una sola llamada a First() al final de una consulta, por ejemplo). ejecución diferida significa que es igual de eficaz utilizar una expresión de consulta y asignar el resultado a una variable, y luego utilizar notación con puntos usando esa variable:

var query = from x in y 
      orderby z 
      group x by x.Name into groups 
      // etc 
      select foo; 

var page = query.Skip(50).Take(10); 

Como han dicho otros, las expresiones de consulta sólo están traducidos al " normal "C# 3 sin expresiones de consulta, por lo que no hay penalización por hacer esto.

+3

+1 nuevamente para dividir los dos cuando desee usarlos juntos en lugar de colocar el primero entre paréntesis y virar el resto al final. – Shibumi

3

La notación Lambda es más nítida y más concisa.Me resulta molesto que si tiene una expresión Lambda en cualquier parte dentro de una llamada a método, no puede modificar el código sobre la marcha en modo de depuración ...

+0

¿Funciona Edit & Continue si está utilizando expresiones de consulta? –

+0

@MichaelFreidgeim - No. :-) Una de las cosas que descubrí en los 2 años desde que escribí esta respuesta. –

Cuestiones relacionadas