Home > Software engineering >  C# Include, ThenInclude Select specific fields
C# Include, ThenInclude Select specific fields

Time:09-19

I have the following classes:

  public class Teacher
    {
        Guid ID;
        string Name;
        string Address;
        string Tel;
        ICollection<Student> Students;
    }

    public class Student
    {
        Guid id;
        string Name;
        string Address;
        string Tel;
        ICollection<Teacher> Teachers;
    }

As this is a Many-to-Many relationship, EF would create a Junction Table TeacherStudent. I want to find all teachers and the list of the teacher's students (name only), eg:

Teacher1 name:
  Student1 name,
  Student3 name,
  Student5 name,
  Student9 name

Teacher2 name:
  Student1 name,
  Student2 name,
  Student3 name,
  Student9 name

I've tried:

_context.Teacher.Include(x=>x.TeacherStudent).ThenInclude(y=>y.Student);

This works and Student info is a list under each Teacher. However, I don't want all the info, I only want the name. I've tried SelectMany but it flattened out the data and I get the Teacher's name repeated for each Student. How can get a list of Student names under the Teacher's name and not retrieve the fields I don't need ?

Thanks.

CodePudding user response:

Include is used to eager load related entities. Select is used to project an entity query into a desired data structure, or otherwise retrieve pieces of information about an entity.

So you can get a list of teachers and students' names:

var teachers = _context.Teacher
    .Select(t => new 
    {
        t.Id,
        t.Name,
        Students = t.Students.Select(s => new 
        {
            s.Id,
            s.Name
        }).ToList()
    }).ToList();

What this would return is an anonymous type containing a list of teachers, pulling back just their ID and name, and a collection of Student anonymous types with the student ID and Name.

Typically when reading data with projections it is a good idea to read IDs since you will often want to use this information to either bring up details, remove, or otherwise alter entries.

If I were to use projection, does it mean that EF still would retrieve all the fields before projecting

Projection builds an SQL query to pull back just the fields needed to populate the data structure you request. It doesn't load entities so this is somewhat mutually exclusive to Include. You do not need to "include" related entities to use projection.

Eager Loading with Include is typically something you will use when performing an update. for instance if you are going to be adding or removing student associations to a Teacher, you will want to load the Teacher and associated Students to ensure that the change tracking understands what you are doing when you go to add or remove students from a Teacher.

  • Related