查询多对多关系Entitty Framework(做错了??)

时间:2018-01-17 14:58:52

标签: c# entity-framework many-to-many code-first

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

总结我创建了这样的实体:

 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(); 

我们查看列表中的课程集合值为null。这里发生了什么?,不要EF映射这个并查询SQL以获取信息吗?

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

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

在Wordpress中发现一个我没试过的查询,并添加其他一些代码来实现我想要的目标:

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();
          
  }

//我知道我可以做一个投射来解雇我不需要的所有字段,这只是试一试

我做错了吗?

它有效,但怎么可能?

3 个答案:

答案 0 :(得分:0)

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

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

因此,当您查询学生时,您只需这样做: dbContex.Students.Include(c => c.Courses).ToList();

答案 1 :(得分:0)

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

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

之前完成

你想要所有学生,每个学生都有他所有的课程。如果查看表格,您会看到表格中有更多数据。例如,每个学生都有一个Id,他的每个课程都有相同的StudentId值。因此,如果学生参加20门课程,您将为StudentId转移相同的值21次。

因此,为了提高您的查询效率:只选择您计划使用的学生属性,只选择您感兴趣的这些学生的课程属性。

这将自动解决您的问题:

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();
      });

答案 2 :(得分:0)

如果您执行此查询:

var studentslist = dbContex.Students.ToList(); 

学生列表中的每个项目都会将“课程”集合设为空,因为尽管存在连接/关系(每个表之间),但您没有指定要填充该集合。为此,您可以相应地更改查询:

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

现在,在运行最后一个查询后,如果您在一个/任何项目上获得一个空列表,则表示这些项目(学生)未链接到任何课程。