首页 > 解决方案 > 查询具有特定属性的深层子对象,但返回级联的根对象

问题描述

对不起,这个神秘的标题,我一直在努力解决这个问题。

假设我们有一个这样的模型结构: Schools,有班级,而班级又有学生。我想返回一个学校列表(作为顶级对象),包括学生是男性的班级和学生。

简单的方法是:

var maleStudents = Context.Students
  .Include(s => s.Classes)
  .ThenInclude(c => c.School)
  .Where(s => s.Gender == Gender.Male)

问题是,这会返回一群学生,他们拥有自己的班级和学校副本。如果没有一堆组织,它也很难通过“学校”直观地显示它们。

有没有一个优雅的解决方案,或者在将它全部拉到服务器后是否需要我通常的杂耍?

标签: c#entity-frameworkentity-framework-core

解决方案


从 EF Core 5.0 开始,支持过滤包含,因此您可以按如下方式编写查询:

var schools = Context.Schools
    .Include(s => s.Classes)
    .ThenInclude(c => c.Students.Where(s => s.Gender == Gender.Male));

如果您的目标是 EF Core 的早期版本,则您现有的查询很好,因为您可以GroupBy在客户端中执行 a 来投影您的结构:

var schoolsWithStudents = maleStudents
  .GroupBy(x => x.Classes
  .First().School);

虽然这是假设每个学生只属于与同一所学校相关的班级。


评论后更新

如果您只想带回有男学生的学校,您可以Where在过滤后添加额外的包括:

var schools = Context.Schools
    .Include(s => s.Classes)
    .ThenInclude(c => c.Students.Where(s => s.Gender == Gender.Male))
    .Where(s => s.Classes.Any(c => c.Students.Any(st => st.Gender == Gender.Male)));

推荐阅读