如何优化该EF Core查询,解决冗余加载与性能警告问题?
EF Core 查询优化方案
实现代码
直接改用投影查询替代全量Include加载,可在单次查询内满足所有需求,同时解决现有问题:
var queryResult = await _warehouseContext.Racks .AsNoTracking() // 筛选目标货架 .Where(r => r.Aisle.Room.Number == targetPosition.Room && r.Aisle.Letter == targetPosition.Aisle && r.Position == targetPosition.Rack) .Select(r => new { // 货架及其类型 RackInfo = r, RackType = r.Type, // 目标层板+所属箱体+箱体类型 TargetShelf = r.Shelves.OrderBy(s => s.VerticalPosition) .Skip(targetPosition.ShelfNumber - 1) .Select(s => new { s.Id, s.VerticalPosition, ShelfType = s.Type, Boxes = s.Boxes.Select(b => new { b.Id, BoxType = b.BoxType }).ToList() }).FirstOrDefault(), // 上方相邻层板(仅层板+类型) UpperAdjacentShelf = r.Shelves.OrderBy(s => s.VerticalPosition) .Skip(targetPosition.ShelfNumber) .Select(s => new { s.Id, s.VerticalPosition, ShelfType = s.Type }).FirstOrDefault() }) .FirstOrDefaultAsync();
方案优势
- 无冗余数据:仅目标层板加载箱体信息,其余层板仅返回基础属性和类型,不会加载多余的箱体数据
- 消除查询警告:投影查询不需要加载多组完整的集合导航实体,不会触发多集合查询的拆分警告;如果后续需要拆分查询优化性能,直接追加
.AsSplitQuery()即可 - 支持无跟踪查询:返回结果为自定义投影结构,不存在实体间的循环引用,
AsNoTracking()可正常使用 - 单次查询:整个逻辑可被EF Core完整翻译为SQL,仅需一次数据库请求即可返回所有需要的数据
如果需要强类型返回结果,自定义对应结构的DTO类替换代码中的匿名类即可。
内容的提问来源于stack exchange,提问作者TheSpixxyQ
相关产品推荐
相关产品推荐

