Jak "pozwolić" w wyrażeniu lambda?

Jak mogę przepisać to zapytanie linq do encji z wyrażeniem lambda?
Chcę użyć słowa kluczowego let lub jego odpowiednika w moim wyrażeniu lambda.

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

W przypadku podobnych pytań Jak to co jest komentowane pod moim pytaniem, proponuje

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

Które obliczy średnią dla każdego elementu, podczas gdy w stylu zapytań wspomniałem, niech wyrażenie zapobiega obliczaniu średniej wiele razy.

Author: Reza Owliaei, 2012-02-11

3 answers

Możesz więc użyć składni metody rozszerzenia, która obejmowałaby o jedno wyrażenie lambda więcej niż obecnie używasz. Nie ma let, wystarczy użyć wielowierszowej lambdy i zadeklarować zmienną:

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

Zauważ, że zmieniłem średnie porównanie cen, ponieważ twoje nigdy nie zwróci żadnych wyników (więcej niż 500 i mniej niż 250).

Alternatywą jest

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/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-11 13:09:15

Zasadniczo musisz użyć Select i anonimowego typu, aby dodać średnią do obiektu, a następnie resztę instrukcji.

Nie testowany, ale powinien wyglądać tak:

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);
Uwaga, ostrożnie z tymi konstrukcjami. Za pomocą let tworzy nowy anonimowy typ na obiekt w Twojej kolekcji, zużywa dużo pamięci przy dużych kolekcjach ...

Zobacz szczegóły tutaj: Let in chained extension methods

 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/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:33:13

Inną opcją jest zdefiniowanie tej metody rozszerzenia:

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

Następnie napisz zapytanie tak:

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/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-17 19:36:35