2009-10-22 14 views
7

¿Puedo simplificar esta afirmación con una expresión lambda?Expresión Lambda

var project = from a in accounts 
       from ap in a.AccountProjects 
       where ap.AccountProjectID == accountProjectId 
       select ap; 

Respuesta

3

Honestamente, me parece bastante claro. Creo que un lambda en este caso puede ser menos legible, es decir, algo así como Brandon publicado a continuación.

(robado del puesto de Brandon)

var project = accounts.Select(a => a.AccountProjects) 
         .Where(x => x.AccountProjectID == accountProjectId); 

En lo que se refiere a la legibilidad, creo que un par de bucles es preferible a la solución de lambda, y creo que la solución es preferible a los bucles.

+4

Depende de cómo lo escriba, agregue un salto de línea antes de ".Where" y de repente la lambda es realmente bastante legible. –

+1

Estoy de acuerdo con Ed. Lo que tienes ahora es perfectamente legible, una lambda en realidad no simplifica nada. Esto probablemente sea una cuestión de preferencia si algo. – Brandon

+1

Incluso con el salto de línea, para mí es aún menos legible, pero supongo que es algo subjetivo. Supongo que el punto es; está perfectamente claro, ¡pasa a un problema real! :) –

4
var project = accounts.SelectMany(a => a.AccountProjects) 
         .Where(x => x.AccountProjectID == accountProjectId); 

Si esto es en realidad más simple es una cuestión de gusto.

+0

Creo que las cláusulas de cláusulas múltiples son conceptualmente más simples que las de SelectMany de aplanamiento implícito, pero independientemente de eso, ¿no es el objetivo de la sintaxis de LINQ dar una sintaxis más limpia que estos métodos encadenados? – Joren

+0

Los dos enfoques son conceptualmente equivalentes. Ellos hacen exactamente lo mismo. Son dos formas diferentes de expresar exactamente los mismos conjuntos de operaciones. Como noté en mi respuesta, lo que usted encuentra "más limpio" o "más simple" es una cuestión de gusto. – Mark

2

Estoy de acuerdo con Ed Swangren. Esto parece lo suficientemente conciso y legible.

En realidad, la respuesta a su pregunta depende de 3 cosas:

  1. Lo que se quiere lograr - una mejor legibilidad? ¿mejor interpretación? etc.
  2. El tipo de 'cuentas'
  3. Cómo se va a utilizar la colección resultante.

Si desea un mejor rendimiento, y si 'accounts' es una lista, y la colección resultante se repetirá o pasará a otro método para iterar lo suficientemente pronto después de estas líneas de código, haría algo así :

List<Account> filteredAccounts = new List<Account>(); 
accounts.ForEach(a => { if (a.AccountProjectID == accountProjectId) filteredAccounts.Add(a); }); 

sin duda, es menos legible entonces su declaración de LINQ, pero me gustaría utilizar estas 2 líneas en lugar de accounts.Select .......

Y seguro que es mucho mejor para un rendimiento optimizado, que siempre es importante, creo.

+2

¿Cuál es el beneficio de eso al llamar a 'ToList()' en la consulta LINQ? –

+0

La pregunta no le pidió que la optimizara, sino simplificarla. También está asumiendo una gran idea cuando dice que está "mucho mejor optimizado para el rendimiento". ¿Lo has probado realmente? ¿Tiene datos para respaldar su suposición? – Mark

+0

1. Lo que usted llama simplificación: es una cuestión de gusto. Creo que respondí esta pregunta en mi publicación anterior. 2. Por supuesto que lo probé. De lo contrario, no lo publicaría. El problema no está en llamar a ToList en la consulta. En promedio LINQ para objetos es más de dos veces más lento que las técnicas tradicionales (por ejemplo, iterar utilizando el ciclo foreach). No me creas? Usted puede fácilmente micro-benchmark de simplemente buscarlo en Google. Y ForTodo método de extensión utilizado aquí junto con la expresión lambda le proporciona un rendimiento aún mejor que el ciclo foreach. Me esfuerzo por estudiar lo que cuestan las cosas, créanme – Alexander

0
accounts 
    .SelectMany (
     a => AccountProjects, 
     (a, ct) => 
     new 
     { 
      a = a, 
      ap = ap 
     } 
    ) 
    .Where (t => (t.ap.AccountProjectID == t.a.accountProjectId)) 
    .Select (t => t.ap) 
Cuestiones relacionadas