如何从两个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
相关产品推荐
相关产品推荐

