如果您使用适当的实体框架类定义实现一对多关系,那么您的查询将会简单得多。你甚至不需要使用连接,因为实体框架会为你做到这一点。
看到Entity Framework Configure One-to-Many Relationship
如果一个教师具有零个或多个学生,每个学生都只有一个老师,一个一对多如下建模:
class Teacher
{
public int Id {get; set;}
// a Teacher has zero or more Students:
public virtual ICollection<Student> Students {get; set;}
...
}
class Student
{
public int Id {get; set;}
// a Student has exactly one Teacher, via foreign key TeacherId
public int TeacherId {get; set;}
public virtual Teacher Teacher {get; set;}
...
}
class MyDbContext : DbContext
{
public DbSet<Teacher> Teachers {get; set;}
public DbSet<Student> Students {get; set;}
}
因为适当Code First Conventions使用,这就是模拟师生之间一对多关系所需要的一切。
如果你想要不同的表名或列名,你必须使用属性或流利的API,但ID仍然是一样的:一个教师有一个ICollection它有很多学生,而一个学生有一个外键和一个属性给它的一个教师。
已经正确定义模式使您的查询更简单:
var result = myDbContext.Teachers // from the set of Teachers
.Where(teacher => teacher.TypeId == 2) // take all teachers with TypeId 2
.Select(teacher => new Test() // from every remaining Teacher,
{ // create one Test object
Id = teacher.Id, // With Id is Teach Id
Text = teacher.Text, // Text is teacher.Text
Students = teacher.Students
.Select(student => new StudentDTO() // from every Student of this Teacher
{ // create a StudentDTO object
Id = student.ID, // with Id = student.Id
Name= student.Name, // Name is student.Name
})
.ToList(), // create a list of these StudentDTOs
})
.ToList(); // create a list of all Test objects
我的经验是,因为我我所有的实体框架类的模型正确,我很少有创建的连接了。我通常在收集而不是加入表格。实体框架将知道何时在内部进行连接。
例如:如果你想在老师的所有学生的名字具有一定TeacherCode:
IEnumerable<Student> GetStudentsOfTeacher(string teacherCode)
{
return myDbContext.Students
.Where(student => student.Teacher.TeacherCode == teacherCode);
}
实体框架会做学生,并为您的TeacherId教师的加入。
除了简单的linq查询,正确的建模也隐藏了数据库建模的方式。如果您的内部模型发生变化,您的dbContext用户将不必更改其代码。例如,如果您将教师 - 学生关系更改为多对多关系,这意味着教师可能有许多学生,并且学生可能有许多教师,则您的教师类的定义不会更改,因此只要类不会改变,上面的查询就不会改变。
你得到什么错误? – Maxime
没有收到学生记录在对象中的集合,如果学生表中有两个匹配记录为一个教师记录,则返回2条记录。我期待test.cs应该有{id,text,Students count 2} – PRK
看起来你需要一个“group by”来做你想做的事。 –