Cómo "dejar" en lambda expresión?


¿Cómo puedo reescribir esta consulta linq a Entity on con la expresión lambda?
Quiero usar let palabra clave o un equivalente en mi expresión lambda.

var results = from store in Stores
              let AveragePrice =  store.Sales.Average(s => s.Price)
              where AveragePrice < 500 && AveragePrice > 250

Para algunas preguntas similares como lo que se comenta en mi pregunta, se sugiere

.Select(store=> new { AveragePrice = store.Sales.Average(s => s.Price), store})

Que calculará el precio promedio para cada elemento, mientras que en el estilo de consulta que mencioné, let expresión impide calcular el promedio muchas veces.

Author: Reza Owliaei, 2012-02-11

3 answers

Por lo tanto, puede usar la sintaxis del método de extensión, que implicaría una expresión lambda más de la que está utilizando actualmente. No hay let, solo usa una lambda multilínea y declara una variable:

var results = Stores.Where(store => 
{
    var averagePrice = store.Sales.Average(s => s.Price);
    return averagePrice > 250 && averagePrice < 500;
});

Tenga en cuenta que cambié la comparación de precios promedio, porque el suyo nunca devolvería ningún resultado (más de 500 Y menos de 250).

La alternativa es

var results = Stores.Select(store => new { Store = store, AveragePrice = store.Sales.Average(s => s.Price})
    .Where(x => x.AveragePrice > 250 && x.AveragePrice < 500)
    .Select(x => x.Store);
 40
Author: Jay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-11 13:09:15

Básicamente, necesita usar Select y un tipo anónimo para agregar el promedio a su objeto, seguido del resto de su declaración.

No probado pero debería verse así:

Stores.Select(
x => new { averagePrice = x.Sales.Average(s => s.Price), store = x})
.Where(y => y.averagePrice > 500 && y.averagePrice < 250)
.Select(x => x.store);

Advertencia, tenga cuidado con estas construcciones. Usando let crea un nuevo tipo anónimo por objeto en su colección, consume mucha memoria con colecciones grandes ...

Mira aquí para más detalles: Let in métodos de extensión encadenada

 21
Author: Yoeri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:33:13

Otra opción es definir este método de extensión:

public static class Functional
{
    public static TResult Pipe<T, TResult>(this T value, Func<T, TResult> func)
    {
        return func(value);
    }
}    

Luego escribe tu consulta de esta manera:

var results = Stores
    .Where(store => store.Sales.Average(s => s.Price)
        .Pipe(averagePrice => averagePrice < 500 && averagePrice > 250));
 4
Author: Timothy Shields,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-17 19:36:35