使用EF从多表获取数据,关联ReportProblems与Users表的问题求助
现有代码问题
- 循环内覆盖列表变量:foreach 中每次都给
userdetails整体赋值,之前查询到的用户数据会被直接覆盖,最终只能保留最后一次循环的查询结果 - 类型不匹配:
reportProblemsList是List<ReportProblem>泛型集合,仅能存储ReportProblem类型的对象,你尝试将List<User>类型的userdetails添加到该集合,语法层面就无法通过编译 - 性能损耗:每次循环都发起一次数据库查询,产生N+1查询问题,数据量较大时会严重拖慢接口响应速度
修复方案
方案一:快速修正原有逻辑
如果需要单独存储所有关联的用户列表,修改代码如下:
List<ReportProblem> reportProblemsList = new List<ReportProblem>(); List<User> userdetails = new List<User>(); reportProblemsList = objEntities.ReportProblems.ToList(); foreach(var item in reportProblemsList) { // 单次查询当前举报对应的用户 var currentUserList = objEntities.Users.Where(x => x.UserId == item.Userid).ToList(); // 将本次查询结果追加到总用户列表,而非覆盖 userdetails.AddRange(currentUserList); } // 此时userdetails已经是所有关联用户的集合,不需要再往reportProblemsList里加 // 如果需要把用户和对应的举报问题绑定,建议给ReportProblem类扩展User类型的属性存储,不要混在同一个列表
方案二:优化为批量查询(推荐)
只需要两次数据库查询即可拿到全部数据,性能远高于循环查询:
// 1. 查询全部举报数据 List<ReportProblem> reportProblemsList = objEntities.ReportProblems.ToList(); // 2. 提取所有需要查询的用户ID,去重 var needQueryUserIds = reportProblemsList.Select(x => x.Userid).Distinct().ToList(); // 3. 批量查询所有对应用户 List<User> userdetails = objEntities.Users.Where(x => needQueryUserIds.Contains(x.UserId)).ToList();
如果你的EF上下文已经给ReportProblem和User配置了外键导航属性,还可以用Include一次性关联查询,代码更简洁:
var reportWithUserList = objEntities.ReportProblems.Include(x => x.User).ToList(); // 遍历的时候直接通过item.User就能拿到对应的用户信息
内容的提问来源于stack exchange,提问作者Nic
相关产品推荐
相关产品推荐

