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

如何从两个ItemAmount列表中提取需更新的对象?

问题:筛选需更新的物料数量记录

我正在开发一款应用,支持用户给产品添加对应数量的关联物料,物料、产品、物料使用量分别存在数据库的独立表中。
目前功能基本可用,但更新产品时遇到个问题:用户可以修改关联物料(通过窗体列表框展示、下拉框添加)及对应数量。操作中用List<ItemAmount> itemAmounts记录用户期望的关联物料和数量;加载更新请求时,从数据库获取原始关联数据存入List<ItemAmount> oldData。
我已经实现了新增、删除物料的索引逻辑,但还没完成UPDATE逻辑:需要从possibleUpdatedIndexes里筛选出仅ItemAmount.item.id相同但amount不同的ItemAmount对象,想找个简洁的实现方式,不想用嵌套foreach循环。

相关类定义

public class Item
{
    public string id { get; set; }
    public string name { get; set; }
}

public class ItemAmount
{
    public Item item { get; set; }
    public int amount { get; set; }
}

已实现的索引获取代码

//make a list with the ids of old items
List<string> oldItemIds = new List<string>();
foreach (ItemAmount itm in oldData)
    oldItemIds.Add(itm.item.id);

//make a list with the ids of updated items
List<string> newItemIds = new List<string>();
foreach (ItemAmount itm in itemAmounts)
    newItemIds.Add(itm.item.id);

//List for the indexes of items to delete
List<int> deleteIndexes = new List<int>();
//List for the indexes of items to insert
List<int> insertIndexes = new List<int>();
//List for items that COULD be updated
List<int> possibleUpdatedIndexes = new List<int>();

//fill the lists correctly
int index = 0;
foreach(string newId in newItemIds)
{
    if (oldItemIds.Contains(newId))
        possibleUpdatedIndexes.Add(Convert.ToInt32(index));
    else
        insertIndexes.Add(Convert.ToInt32(index));
    index++;
}
index = 0;
foreach(string oldId in oldItemIds)
{
    if (!newItemIds.Contains(oldId))
    {
        deleteIndexes.Add(index);
    }
    index++;
}

解决方案:用LINQ实现简洁的更新筛选

方法1:基于现有possibleUpdatedIndexes筛选

先将旧数据转为字典(通过item.id快速查找旧数量),再遍历候选索引筛选出数量变化的条目,避免嵌套循环:

// 将旧数据转为字典,key为物料ID,value为原始数量
var oldAmountLookup = oldData.ToDictionary(it => it.item.id, it => it.amount);

// 从候选更新索引中筛选出数量确实变化的条目索引
var actualUpdatedIndexes = possibleUpdatedIndexes
    .Where(idx => 
        oldAmountLookup.TryGetValue(itemAmounts[idx].item.id, out int oldAmount) && 
        itemAmounts[idx].amount != oldAmount)
    .ToList();

方法2:直接关联新旧数据获取需更新条目

如果需要同时获取新旧数据的对比结果,可以用LINQ的Join操作:

// 关联新旧数据,筛选出ID相同但数量不同的条目
var updatedItemPairs = oldData
    .Join(itemAmounts, 
          old => old.item.id, 
          newItem => newItem.item.id, 
          (old, newItem) => new { OldRecord = old, NewRecord = newItem })
    .Where(pair => pair.OldRecord.amount != pair.NewRecord.amount)
    .ToList();

额外优化:用LINQ简化现有索引获取代码

原来的索引获取逻辑也可以用LINQ简化,替代foreach循环:

var oldItemIds = oldData.Select(it => it.item.id).ToList();
var newItemIds = itemAmounts.Select(it => it.item.id).ToList();

// 获取新增物料的索引
var insertIndexes = itemAmounts
    .Select((it, idx) => new { Item = it, Index = idx })
    .Where(x => !oldItemIds.Contains(x.Item.item.id))
    .Select(x => x.Index)
    .ToList();

// 获取候选更新物料的索引
var possibleUpdatedIndexes = itemAmounts
    .Select((it, idx) => new { Item = it, Index = idx })
    .Where(x => oldItemIds.Contains(x.Item.item.id))
    .Select(x => x.Index)
    .ToList();

// 获取需删除物料的索引
var deleteIndexes = oldData
    .Select((it, idx) => new { Item = it, Index = idx })
    .Where(x => !newItemIds.Contains(x.Item.item.id))
    .Select(x => x.Index)
    .ToList();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 03:43:21