如何使用LINQ根据ID从列表提取指定值并赋值到新列表
优化关联赋值方案
原代码中通过遍历列表匹配ID的方式效率较低,尤其是数据量较大时。可以通过字典映射的方式优化关联逻辑,快速将smallZonesLoadedAmount中的LoadedWeight赋值到smallZoneInfo的TotalCargo字段。
优化后完整代码
// 1. 计算每个Storage的总LoadedWeight(原逻辑不变) var smallZonesLoadedAmount = UnitOfWork.Select<LoadingDocumentObject>() .Where(x => x.LoadedWeight > 0 && x.StorageId.HasValue) .GroupBy(x => x.StorageId) .Select(group => new { StorageId = group.Key, LoadedWeight = group.Sum(y => y.LoadedWeight) }) .ToList(); // 2. 将结果转为字典,实现O(1)时间复杂度的ID查找 var storageWeightMap = smallZonesLoadedAmount.ToDictionary( item => item.StorageId.Value, item => item.LoadedWeight ); // 3. 构建Zone信息并关联LoadedWeight var smallZoneInfo = storages.Where(x => !string.IsNullOrEmpty(x.Number)) .GroupBy(y => y.Number) .Select(z => new ZoneInformationView { ZoneName = z.Key, // 需求1:当前Zone下所有Storage的LoadedWeight总和(推荐) TotalCargo = z.Sum(storage => storageWeightMap.TryGetValue(storage.Id, out var weight) ? weight : 0 ), // 需求2:仅取当前Zone下第一个匹配的LoadedWeight(与原代码逻辑一致) // TotalCargo = z.Select(storage => // storageWeightMap.TryGetValue(storage.Id, out var weight) ? weight : 0 // ).FirstOrDefault(), ZonePermissibleUsage = 0, CargoWithLongestStoringTimeInDays = 0, AverageLoadingUnloadingInDays = 0, }).ToList();
关键优化点
- 字典映射提升效率:将
smallZonesLoadedAmount转为字典后,通过StorageId查找LoadedWeight的时间复杂度从O(n)降到O(1),避免了重复遍历列表。 - 安全取值:使用
TryGetValue避免因StorageId不存在而抛出异常,同时可以自定义默认值(示例中用0)。 - 灵活适配需求:
- 如果每个Zone对应多个Storage,需要总和则用
Sum; - 如果仅需单个匹配值,保留
FirstOrDefault即可。
- 如果每个Zone对应多个Storage,需要总和则用
内容的提问来源于stack exchange,提问作者Deivydas
相关产品推荐
相关产品推荐

