EF Core 3中如何合并两个查询并返回List<Submission>类型结果
EF Core 3 合并查询实现方案
核心思路
EF Core 3 不支持过滤/排序Include(该特性从EF Core 5才开始支持),因此无法直接通过Include+ThenInclude实现关联Application下取最新History的Member值的逻辑。可以直接在Submission的查询投影中完成关联Application的字段映射,将两次查询合并为单条SQL执行,最终返回List<Submission>类型结果。
实现代码
基础写法
var result = await context.Submissions .Select(s => new Submission { Id = s.Id, Name = s.Name, ApplicationId = s.ApplicationId, Application = s.Application == null ? null : new Application { Id = s.Application.Id, Member = s.Application.Histories .OrderByDescending(h => h.ModifiedDate) .FirstOrDefault() != null ? s.Application.Histories.OrderByDescending(h => h.ModifiedDate).FirstOrDefault().Member : null } }) .ToListAsync();
简化写法(避免重复排序逻辑)
用查询语法的let关键字提取最新历史记录的逻辑,EF Core 3会自动优化SQL,不会产生重复查询:
var result = await ( from s in context.Submissions let latestHistory = s.Application == null ? null : s.Application.Histories.OrderByDescending(h => h.ModifiedDate).FirstOrDefault() select new Submission { Id = s.Id, Name = s.Name, ApplicationId = s.ApplicationId, Application = s.Application == null ? null : new Application { Id = s.Application.Id, Member = latestHistory.Member } } ).ToListAsync();
注意事项
- 上述写法在EF Core 3下会被翻译为单条SQL执行,不会触发客户端评估,性能优于原有的两次查询逻辑
- 投影过程中需要显式映射Submission、Application实体中你需要使用的所有属性,未映射的属性会保留类型默认值
- 该写法不会加载Application下的完整Histories集合,只会查询你需要的Member字段,减少不必要的数据传输
内容的提问来源于stack exchange,提问作者user989988
相关产品推荐
相关产品推荐

