1

私は次のlinqステートメントを作成しましたが、どういうわけか単純化できると感じずにはいられません。目的は、List<IEnumberable<Counterparty>>(クエリのcounterpartyStatic)オブジェクトを取得し、Counterparty.CounterpartyIdと等しいClientIdを持つOrdersを見つけることです。これらの注文では、Counterparty.DescriptionFieldと一致するようにフィールドClientDescを更新する必要があります。これが完了したら、更新されたすべての注文を渡すイベントを発生させる必要があります。

OrderCacheは、明らかでない場合の辞書です。

既存のコードは次のとおりです。

var updates = new List<Order>();
        lock (CacheLock)
        {
            counterpartyStatic.ToList().ForEach(cachedList =>
                cachedList.ToList().ForEach(
                    counterparty =>
                    {
                        var orders = OrderCache.Where(kvp => kvp.Value.Client == counterparty.CounterpartyId);
                        orders.ToList().ForEach(kvp =>
                        {
                            kvp.Value.ClientDesc = counterparty.Description;
                            updates.Add(kvp.Value);
                        });
                    }));
        }

        RaiseEvent(updates);

助けてくれてありがとう

4

2 に答える 2

4

(私はこれに対する長い答えを書きました、しかしそれから私のラップトップは墜落しました。Grrr。)

LINQクエリを記述して、関心のあるすべての値を見つけてから、ミューテーションを個別に実行します。それで:

var query = from cachedList in counterpartyStatic
            from counterparty in cachedList
            join order in OrderCache.Values // Your query never uses the key
              on counterparty.CounterpartyId equals order.Client
            select new { Order = order, counterparty.Description };

var list = query.ToList(); // Avoid joining more than once

// Now do the update
foreach (var entry in list)
{
    entry.Order.ClientDesc = entry.Description;
}

// Now raise the events
RaiseEvents(list => list.Select(entry => entry.Order)); // Add ToList if needed
于 2012-08-23T16:29:17.007 に答える
4

あなたの「クエリ」が実際に副作用を引き起こすことを意図していることを考えると (つまり、深くネストされたループで値の ClientDesc を変更している)、LINQ を使用する代わりにループを使用してこれを記述することをお勧めします。これにはいくつかの利点があります - を使用するためだけにリストを作成するのではなくList<T>.ForEach、意図がはるかに明確です:

var updates = new List<Order>();

lock (CacheLock)
{
    foreach(var cachedList in counterpartyStatic)
    {
        foreach(var counterparty in cachedList)
        {
             var orders = OrderCache.Where(kvp => kvp.Value.Client == counterparty.CounterpartyId);
             foreach(var kvp in orders)
             {
                  kvp.Value.ClientDesc = counterparty.Description;
                  updates.Add(kvp.Value);
             }
         }
    }

    RaiseEvent(updates);
}

これはオリジナルと同じくらい短いですが、何が起こっているかという点でははるかに明確です。

List<T>.ForEach回避することが有益である理由については、 Eric Lippert の "foreach" vs "ForEach"を参照してください。 List<T>.ForEachそれを取り巻く問題を考慮して、新しいWindowsストアアプリからも削除されました.

于 2012-08-23T16:10:12.707 に答える