1

我已经编写了以下 linq 语句,但我不禁觉得它可以以某种方式简化。目的是获取一个List<IEnumberable<Counterparty>>(查询中的counterpartyStatic)对象并找到ClientId 等于Counterparty.CounterpartyId 的订单。然后这些订单应该更新字段 ClientDesc 以匹配 Counterparty.DescriptionField。完成此操作后,我需要引发一个事件,传递所有已更新的订单。

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

鉴于您的“查询”确实是为了引起副作用(即:您在深层嵌套循环中更改值的 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" 与 "ForEach"List<T>.ForEach考虑到围绕它的问题,甚至已将新的 Windows 应用商店应用程序删除。

于 2012-08-23T16:10:12.707 回答
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 回答