我有表老师和表学生,表“老师”中的每条记录在表“学生”中都有多条记录。这是我的模特班
public class Test
{
public int Id { get; set; }
public string Text { get; set; }
public List<StudentsDTO> Students{ get; set; }
}
这是我的LINQ查询试图获取记录
var st = (from tt in context.Teachers
join ss in context.Students
on tt.ID equals ss.teacherID
where tt.TypeID == 2
select new Test
{
Id = tt.ID,
Text = tt.Text,
Students= new List<StudentsDTO>()
{
new StudentsDTO()
{
Name= ss.Name,
Id= ss.StudentID
}
}.ToList()
}).ToList();
return st;
无法在教师表中为每条记录收集学生,该怎么办?
最佳答案
如果您为一对多关系使用了正确的实体框架类定义,则查询将更加简单。您甚至不必使用联接,因为Entity Framework会为您执行此操作。
见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);
}
实体框架将为您完成Student和Teachers on TeacherId的加入。
如果要进行组联接(一个包含所有子项的项目,一个包含所有学生的教师的项目),请从一侧开始。如果要进行平口聚会(一位学生和一位老师),请从多方面开始。
除了更简单的linq查询外,正确的建模还隐藏了数据库建模的方式。如果内部模型发生更改,则dbContext的用户无需更改其代码。
例如,如果您将“师生”关系更改为“多对多”关系,这意味着“老师”可能有很多学生,而“学生”可能有很多老师,则您的“老师”类的定义不会更改,因此上面的查询会赢只要班级不变,就不必改变。
关于c# - Linq查询以选择新语句返回所有记录,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45154987/