You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将库存更新的嵌套foreach简化为单个循环(LINQ实现)

优化仓库库存与预留项更新代码:嵌套循环转单循环+LINQ优化

需求说明

现有warehouseReservationItems(仓库预留项列表)和ExistingInventories(现有库存列表)两个集合,需根据输入的processedItems列表完成数据更新。当前实现采用嵌套foreach循环:外层遍历processedItems条目匹配对应仓库预留项,内层遍历BinInventoryList匹配库存,执行预留量、在手量更新及错误校验。需要将嵌套循环简化为单个foreach循环,结合LINQ优化查询逻辑。

输入结构示例

// processedItems输入列表结构示例
{
  "reservationId": 0,
  "warehouseId": 0,
  "itemList": [
    {
      "itemId": "string",
      "rejected": true,
      "binInventoryList": [
        {
          "binId": 0,
          "qtyFilled": 0
        }
      ]
    }
  ]
}

当前实现代码(嵌套循环版)

foreach (var item in processedItems) // 遍历输入的每个条目
{
    // 匹配对应的仓库预留项
    var modifiedItem = warehouseReservationItems?.FirstOrDefault(wri => wri.ItemId == item.ItemId);

    // 筛选需要更新的库存项
    var inventoriesToUpdate = item.BinInventoryList
        .SelectMany(rib => existingInventories.Where(winv => winv.ItemId == modifiedItem.ItemId && rib.BinId == winv.BinId))
        .ToList();
    
    foreach (var modifiedInventory in inventoriesToUpdate)
    {
        // 匹配当前库存对应的Bin信息
        var bin = item.BinInventoryList.FirstOrDefault(bin => bin.BinId == modifiedInventory.BinId);
        
        // 更新预留量
        if (modifiedItem.QtyFilled <= modifiedItem.QtyOrdered)
        {
            if (modifiedItem.QtyFilled + bin.QtyFilled > modifiedItem.QtyOrdered)
            {
                modifiedInventory.QtyReserved = (modifiedInventory.QtyReserved - modifiedItem.QtyOrdered) + modifiedItem.QtyFilled;
            }
            else
            {
                modifiedInventory.QtyReserved -= bin.QtyFilled; // 扣除已填充的预留量
            }
        }
        
        // 更新在手库存量
        if (bin.QtyFilled <= modifiedInventory.QtyOnHand)
        {
            modifiedItem.QtyFilled += bin.QtyFilled; // 累计已填充数量
            modifiedInventory.QtyOnHand -= bin.QtyFilled; // 从在手库存中扣除已填充量
        }
        else
        {
            // 记录错误:填充量超过在手库存
            _errorDictionary.Add($"{modifiedInventory.ItemId}({modifiedInventory.BinId})", 
                new[] { $"填充数量({bin.QtyFilled})超过在手库存数量({modifiedInventory.QtyOnHand})" });
        }
        updatedInventory.Add(modifiedInventory);
    }
    // 更新预留项状态
    modifiedItem.SetReservationItemStatus(modifiedItem.QtyFilled, modifiedItem.QtyOrdered);
}

优化后的单循环+LINQ实现

核心思路是用LINQ的Join操作提前关联processedItems、仓库预留项、Bin信息、现有库存,生成包含所有必要数据的扁平集合,再通过一次foreach遍历完成所有更新,避免嵌套循环和重复查询。

// 提前关联所有需要的数据,生成扁平集合
var updateData = processedItems
    // 关联仓库预留项
    .Join(warehouseReservationItems, 
          item => item.ItemId, 
          resItem => resItem.ItemId, 
          (item, resItem) => new { item, resItem })
    // 展开每个条目下的BinInventoryList
    .SelectMany(j => j.item.BinInventoryList.Select(bin => new { j.item, j.resItem, bin }))
    // 关联对应的现有库存
    .Join(existingInventories, 
          j => new { j.resItem.ItemId, j.bin.BinId }, 
          inv => new { inv.ItemId, inv.BinId }, 
          (j, inv) => new { j.resItem, j.bin, inv })
    .ToList();

// 单循环完成所有更新操作
foreach (var data in updateData)
{
    var modifiedItem = data.resItem;
    var bin = data.bin;
    var modifiedInventory = data.inv;
    
    // 更新预留量逻辑
    if (modifiedItem.QtyFilled <= modifiedItem.QtyOrdered)
    {
        if (modifiedItem.QtyFilled + bin.QtyFilled > modifiedItem.QtyOrdered)
        {
            modifiedInventory.QtyReserved = (modifiedInventory.QtyReserved - modifiedItem.QtyOrdered) + modifiedItem.QtyFilled;
        }
        else
        {
            modifiedInventory.QtyReserved -= bin.QtyFilled;
        }
    }
    
    // 更新在手库存逻辑
    if (bin.QtyFilled <= modifiedInventory.QtyOnHand)
    {
        modifiedItem.QtyFilled += bin.QtyFilled;
        modifiedInventory.QtyOnHand -= bin.QtyFilled;
        updatedInventory.Add(modifiedInventory);
    }
    else
    {
        _errorDictionary.Add($"{modifiedInventory.ItemId}({modifiedInventory.BinId})", 
            new[] { $"填充数量({bin.QtyFilled})超过在手库存数量({modifiedInventory.QtyOnHand})" });
    }
}

// 统一更新所有预留项的状态(去重避免重复调用)
foreach (var resItem in updateData.Select(d => d.resItem).Distinct())
{
    resItem.SetReservationItemStatus(resItem.QtyFilled, resItem.QtyOrdered);
}

优化点说明

  • 用LINQ多表关联替代嵌套循环和重复的FirstOrDefault查询,减少冗余操作,提升代码可读性
  • 提前整合所有数据为扁平集合,避免内层循环中重复查找Bin信息
  • 预留项状态更新统一放到循环外(去重处理),减少重复调用次数

内容的提问来源于stack exchange,提问作者Andi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 11:21:15