查询多对多关系实体框架(做错了??)

Querying Many to Many relationships Entitty Framework (doing wrong?? )

我一直在研究这个主题,并找到了一种在我的项目中实现这个查询的方法,但我不确定这里是否有问题。请帮忙

总而言之,我创建了这样的实体:

 class Student
{
public int StudentId { get; set; }
public string Name { get; set; }

public ICollection<Courses> Courses {get;set;} //or public List <Courses> {get;set;}
}

class Course
{
public int CourseId { get; set; }
public string Name { get; set; }

public ICollection<Students> Students {get;set;} //or public List<Students> {get;set;}
}





// We can see here that the database creates the Join Table Correctly


我想做的事情:

在网格视图中显示每个学生,并为每个学生显示他们注册的课程。

如果我做了一个简单的查询,比如

dbContex.Students.ToList(); 

我们查看列表中的 Collection of courses 值为空。这里发生了什么?EF 不应该映射它并查询 SQL 以获取信息吗?

在此之后你无法解决问题,因为我发现的信息使用的是框架的其他方法(我认为是 Diagram First)并且他们在实体图中设置了一些东西。



我是如何解决这个问题的:

在 Wordpress Post 中找到一个我没有尝试过的查询,然后添加一些其他代码行来实现我想要的:

aux_S = contexto.Students.ToList();




 foreach(var element in aux_S)
         
   {
                
element.Courses= contexto.Courses.Where(c => c.Students.Any(s => s.StudentId == element.StudentId)).ToList();
          
  }

// 我知道我可以做一个投影来忽略所有我不需要的字段,这只是为了尝试一下

我这样做错了吗?

成功了,但怎么可能呢?

您没有延迟加载,如果您添加 virtual 如下:public virtual ICollection<Courses> Courses {get;set;} 您应该加载课程。

但是,我建议使用延迟加载,因为它可能会导致性能问题,你想要做的是预加载。

所以当你查询你的学生时,你只需这样做: dbContex.Students.Include(c => c.Courses).ToList();

数据库查询中速度较慢的部分之一是将数据传输到您的计算机。因此,最好只传输您计划使用的数据。

当您在 entity framework 中使用 LINQ 时,使用 Queryable.Select 是准确指定要传输的数据的好方法。这通常在您最终的 ToList / ToDictionary / FirstOrDefault / Single / ...

之前完成

您想要所有学生,每个学生都有他的所有课程。如果您查看您的表格,您会发现表格中的数据比您想要的多。例如,每个学生都有一个 Id,他的每个课程都有相同的 StudentId 值。因此,如果一个学生参加了 20 门课程,您将传输相同的 StudentId 值 21 次。

因此,为了使您的查询更高效:Select 仅包含您计划使用的学生的属性,以及您感兴趣的这些学生的课程的属性。

这将自动解决您的问题:

var result = myDbcontext.Students

    // if you don't want all Students, use a Where:
    .Where(student => student.City = "Guadalajara")

    // Select only the properties you plan to use:
    .Select(student => new
    {
        Id = student.Id,
        Name = student.Name,
        Birthday = student.Birthday,
        Address = new 
        {
            Street = student.Street,
            City = student.City,
            ...
         }

         Courses = student.Courses
             // if you don't want all courses: use a where
             .Where(course => course.Start.Year == 2018)
             // again: select only the properties you plan to use
             {
                  Name = course.Name,
                  Location = course.Location,
                  ...
                  // One of the useless properties to transfer:
                  // StudentId = course.StudentId
              })
              .ToList();
      });

如果执行此查询:

var studentslist = dbContex.Students.ToList(); 

studentslist 上的每个项目都会有 'Courses' 集合 null,因为尽管 connection/relation 存在(在每个 table 之间),但您没有指定您想要那个集合人口稠密。为此,您可以相应地更改您的查询:

var studentslist = dbContex.Students.Include(p => p.Courses).ToList();

现在,在 运行 最后一次查询之后,如果您在 one/any 项上得到一个空列表,则意味着这些项(学生)未链接到任何课程。