优化用户组数据获取代码:移除第二个循环,为无组ID赋默认值
优化方案:移除额外循环,高效生成默认值
可以通过LINQ分组+字典查找的方式合并两次循环,同时提升整体查询效率,具体实现如下:
优化后的代码
public async Task<ResponseBase> GetUserGroups(List<int> userId) { var groups = await _userRepository.GetUserGroupsToDownload(); var userGroups = await _userRepository.GetUserGroupsToDownload(userId); // 将groups转成字典,避免重复遍历查找组名称 var groupDict = groups.ToDictionary(g => g.Id, g => g.Name); // 将用户组按UserId分组,快速获取每个用户的所有组 var userGroupDict = userGroups.GroupBy(ug => ug.UserId).ToDictionary(g => g.Key, g => g.ToList()); var aLst = new List<UserGroupDto>(); // 遍历所有传入的UserId,一次循环完成所有数据生成 foreach (var id in userId) { if (userGroupDict.TryGetValue(id, out var userGroupList)) { // 存在用户组,为每个组生成Dto foreach (var group in userGroupList) { var result = new UserGroupDto { GroupId = group.GroupId, Id = group.UserId, EnterpriseId = group.EnterpriseId, // 从字典直接取组名,不存在则为空 Name = groupDict.TryGetValue(group.GroupId, out var name) ? name : "", Enabled = true // 原代码中Any判断恒为true,因当前group本身来自userGroups }; aLst.Add(result); } } else { // 无对应组,生成默认值Dto aLst.Add(new UserGroupDto { GroupId = 0, Id = id, EnterpriseId = 0, Name = "", Enabled = false }); } } return ResponseBase.WithSuccess().WithData(aLst); }
关键优化点说明
- 字典查找替代线性遍历:将
groups转成Dictionary<int, string>后,组名称的查找从O(n)变为O(1),避免原代码中每次Where+FirstOrDefault的性能损耗 - 分组处理用户组:通过
GroupBy将userGroups按UserId分组,后续判断用户是否有组、获取用户所有组的操作都是O(1),比原代码中维护ids列表再用Contains判断(O(n))高效得多 - 单循环完成所有逻辑:直接遍历传入的
userId列表,在同一个循环内处理"有组用户"和"无组用户"的情况,移除了原有的第二个循环,代码更简洁
补充说明
原代码中result.Enabled = userGroups.Any(ug => ug.GroupId == group.GroupId)的逻辑其实恒为true(因为当前group本身就来自userGroups),所以优化后直接设为true,如果实际业务逻辑有特殊判断,可以根据需求调整。
内容的提问来源于stack exchange,提问作者user8512043
相关产品推荐
相关产品推荐

