实体框架使用过滤器从一个表到多个表中选择不同的值

时间:2019-03-08 08:02:08

标签: c# entity-framework entity

我正在尝试在EF中编写查询。

考虑这种关系:

example

目标是让教师拥有完整的学生集合,他们在一定的过滤时间段(从-到)之间保持活跃。

我写了以下查询:

var filtered = _context.Teachers
                       .Join(_context.Students, // Target
                             fk => fk.Id, // FK
                             pk => pk.teacherId, // PK
                             (fk, pk) => new { teach = fk, students = pk }
                            )
                       .Where(i => i.students.date_active >= from &&
                                   i.students.date_active <= to)
                       .OrderBy(i => i.teach.name)
                       .Select(i => i.teach)
                       .Include(i => i.Students)
                       .AsNoTracking();

通过此查询,我得到了重复的老师。因此,我只添加Distinct()运算符,然后便有了老师。但是后来我的老师对象仍然包含所有学生。我只想要那个时期的学生。对获得良好结果有帮助吗?

List<Dto.Teacher> list = filtered.Select(i => Dto.Teacher
                                              {
                                                  id = i.Id,
                                                  name = i.name
                                                  Students = i.Students.Select(j => new Dto.Student
                    {
                        id = i.id,
                        date_active = i.date_active,
                    }).ToList(),
                }).ToList();

public class Teacher() 
{ 
    public int id { get; set; }
    public string name { get; set; }

    public List<Dto.Student> Students { get; set; }
}

1 个答案:

答案 0 :(得分:1)

在使用诸如EF之类的ORM时,应尽可能避免使用join运算符。

根据您的情况,您可以尝试以下操作(可能会有所不同):

_context.Teachers.
    Where(t => t.Sudents.Any(s => s.date_active >= from &&
        s.date_active <= to)
    ).
    Select(t => new {
        teacher = t,
        activeStudents = t.Students.Where(s => s.date_active >= from &&
        s.date_active <= to)
    });