44

このlinqクエリをラムダ式でエンティティに書き換えるにはどうすればよいですか?ラムダ式でletキーワードまたは同等のもの
を使用したいと思います。

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

私の質問の下でコメントされているもののようないくつかの同様の質問については、

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

これは各アイテムのAveragePriceを計算しますが、前述のクエリスタイルでは、が平均を何度も計算しないようにします。

4

4 に答える 4

48

したがって、拡張メソッド構文を使用できます。これには、現在使用しているよりも1つのラムダ式が含まれます。ありませんlet。複数行のラムダを使用して変数を宣言するだけです。

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

平均価格の比較を変更したことに注意してください。これは、結果が返されないためです(500を超え250未満)。

代替案は

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);
于 2012-02-11T13:02:28.790 に答える
27

基本的に、Selectと匿名タイプを使用してオブジェクトに平均を追加し、その後にステートメントの残りの部分を追加する必要があります。

テストされていませんが、次のようになります。

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);

警告:これはLinq-to-Entitiesでうまく機能しますが、Linq-to-Objectsのこれらの構造には注意してください。を使用letすると、コレクション内のオブジェクトごとに新しい匿名タイプが作成され、大きなコレクションでは大量のメモリを消費します。

詳細については、こちらをご覧ください: 連鎖拡張メソッドを導入する

于 2012-02-11T13:03:14.087 に答える
4

別のオプションは、この拡張メソッドを定義することです。

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

次に、次のようにクエリを記述します。

var results = Stores
    .Where(store => store.Sales.Average(s => s.Price)
        .Pipe(averagePrice => averagePrice < 500 && averagePrice > 250));
于 2013-08-07T17:35:43.383 に答える
1

インラインアウト宣言を使用すると、他のすべての回答で使用されるラムダのオーバーヘッドを回避できます。

public static class FunctionalExtensions
{
    public static T Assign<T>(this T o, out T result) =>
        result = o;
}

そしてそれをこのように呼ぶ

var results = Stores
    .Where(store => store.Sales
        .Average(s => s.Price)
        .Assign(out var averagePrice) < 500 && averagePrice > 250);
于 2019-10-05T15:12:28.613 に答える