ASP.NET Core中Entity Framework查询嵌套子集并映射到ViewModel的方法
实现方案
你可以通过「关联数据加载 + 内存分组投影」或者「服务端直接投影」两种方式实现需求,以下是完整可运行的代码:
方案1:先加载全量关联数据再分组(适合中小数据量,调试更直观)
首先修正你原有查询中的导航属性拼写错误(原代码中ScheduleOffice少了末尾的s,与实体类定义的导航属性名不匹配,会导致关联数据加载失败),再对查询结果做分层投影即可:
// 加载所有需要的关联数据 var dayProgramList = _db.DayProgramOffice .Include(c => c.ScheduleOffices) .ThenInclude(d => d.TypeConsultaion) .ToList(); // 分层分组映射到ViewModel List<Day> days = dayProgramList.Select(dayProgram => new Day { day = dayProgram.Day, Types = dayProgram.ScheduleOffices // 按咨询类型分组 .GroupBy(schedule => schedule.TypeConsultaion) .Select(typeGroup => new TypeConViewModel { TypeName = typeGroup.Key.TypeName, Hovers = typeGroup.Select(schedule => new HoverViewModel { Hover = schedule.Time }).ToList() }).ToList() }).ToList();
映射完成后的days集合即可直接传给视图使用。
方案2:服务端直接投影(适合大数据量,性能更优)
不需要手动写Include加载全量实体,EF Core会自动根据投影的字段生成最优SQL,只查询你需要的字段,性能更高:
List<Day> days = _db.DayProgramOffice .Select(dayProgram => new Day { day = dayProgram.Day, Types = dayProgram.ScheduleOffices .GroupBy(schedule => schedule.TypeConsultaion) .Select(typeGroup => new TypeConViewModel { TypeName = typeGroup.Key.TypeName, Hovers = typeGroup.Select(schedule => new HoverViewModel { Hover = schedule.Time }).ToList() }).ToList() }).ToList();
注意事项
- 视图代码中你写的
@item3.hover属性名首字母小写,与HoverViewModel中定义的大写Hover属性不匹配,需要修正为@item3.Hover避免运行时报错。 - 如果你使用的是EF Core 3.0以下版本,服务端GroupBy可能存在翻译问题,优先使用方案1即可。
内容的提问来源于stack exchange,提问作者sajaf
相关产品推荐
相关产品推荐

