如何在EF Core的SELECT列表中编写子查询实现跨表取值?
问题:将指定SQL转换为EF Core代码
原SQL语句逻辑:查询Scheduler.Schedules表中ScheduleType = 2的所有数据,同时通过标量子查询从Scheduler.ProgramSettings表中获取满足ps.DefaultStartDay = s.Id的DefaultStartDay值,作为结果集的DefaultStartDay字段。
原SQL代码:
Select *, (Select DefaultStartDay from Scheduler.ProgramSettings ps where ps.DefaultStartDay = s.Id ) [DefaultStartDay] from Scheduler.Schedules s where ScheduleType = 2;
你尝试的错误EF Core代码:
var model = _context.Schedules .Where(s => s.ScheduleType == 2) .Select(rv => new ProgramSetting { Id = rv.Id, ProgramTemplateId = rv.ProgramTemplateId, IsActive = rv.IsActive, DefaultStartDay = rv.Id }).ToArray();
错误原因:直接将rv.Id赋值给DefaultStartDay,没有实现原SQL中子查询从ProgramSettings表匹配数据的逻辑。
正确的EF Core实现代码
要还原原SQL的标量子查询逻辑,可在Select投影中嵌入子查询:
var model = _context.Schedules .Where(s => s.ScheduleType == 2) .Select(s => new ProgramSetting { Id = s.Id, ProgramTemplateId = s.ProgramTemplateId, IsActive = s.IsActive, // 对应原SQL的标量子查询逻辑 DefaultStartDay = _context.ProgramSettings .Where(ps => ps.DefaultStartDay == s.Id) .Select(ps => ps.DefaultStartDay) .FirstOrDefault() // 无匹配项时返回null,和原SQL子查询行为一致 }).ToArray();
补充说明
- 若
ProgramSettings中满足条件的记录最多一条,用FirstOrDefault()即可,和原SQL子查询行为完全匹配; - 若需确保子查询返回唯一值,可改用
SingleOrDefault(),但存在多条匹配时会抛出异常; - 也可通过
Join实现类似逻辑,但上述写法更贴合原SQL的标量子查询语义。
内容的提问来源于stack exchange,提问作者Abuzar Ansari
相关产品推荐
相关产品推荐

