如何使用 LINQ 加入多个 table,包括加入-table(由 Entity Framework 自动生成)
How can I join multiple tables including a join-table (auto-generated by Entity Framework) using LINQ
我需要使用多个连接进行查询,其中包括从多对多关系生成的连接table。如果我直接查询数据库,它会工作,但我需要在我的一个控制器中进行查询,因为我没有 join-table 的模型,我无法进行简单的连接一个 DbSet,我已经被困了几个小时试图找出它是如何工作的。
这是我在数据库中的表:
考试
- (PK) 身份证
- (FK) ClassId
关系:* 到 1
类
- (PK) 身份证
关系:1 到 *
类学生
- (PK) ClassId
- (PK) 学号
关系:* 到 1
学生
- (PK) 身份证
- (FK) PersonId
关系:1 对 1
人
- (PK) 身份证
- 名字
- 姓氏
这些是我的模型:
public class Exam
{
public int Id { get; set; }
public short ClassId { get; set; }
public Class Class { get; set; }
}
public class Class
{
public Class()
{
this.Students = new HashSet<Student>();
}
public int Id { get; set; }
public virtual ICollection<Student> Students { get; set; }
}
public class Student
{
public Student()
{
this.Classes = new HashSet<Class>();
}
public int Id { get; set; }
public virtual ICollection<Class> Classes { get; set; }
}
public class Person
{
public int Id { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
}
我正在尝试获取此查询...
SELECT stu.Id, peo.FirstName, peo.LastName
FROM Exams AS exa
JOIN Classes AS cla
ON cla.Id = exa.ClassId
JOIN ClassesStudents AS clastu
ON clastu.ClassId = cla.Id
JOIN Students AS stu
ON stu.Id = clastu.StudentId
JOIN People AS peo
ON peo.Id = stu.PersonId
WHERE exa.Id = 1;
... 在我的 Controller 中有点像这样工作:
public ActionResult CreateMark(int id)
{
var students = (from exams in _context.Exams
join classes in _context.Classes
on exams.ClassId equals classes.Id
join classesstudents in _context.ClassesStudents // that
on classes.Id equals classesstudents.ClassId // part
join students in _context.Students // doesn't
on classesstudents.StudentId equals students.Id // work
join people in _context.People
on students.PersonId equals people.Id
where exams.Id == id
select new
{
Id = students.Id,
FullName = people.FirstName + " " + people.LastName
}).ToList();
如果有任何帮助,我将不胜感激!
编辑:
我设法让它与以下代码一起工作,但是有没有一种方法可以在一次查询中使用更少的代码来完成它?
public ActionResult Create(int id)
{
var class = (from exa in _context.Exams
join cla in _context.Classes
on exa.ClassId equals cla.Id
where exa.Id == id
select new
{
ClassId = cla.Id,
Students = cla.Students
}).ToList();
var classWithStudents= (from cla in class
from stu in cla.Students
select new
{
Id = stu.Id,
PersonId = stu.PersonId
}).ToList();
var students = (from stu in classWithStudents
join peo in _context.People
on stu.PersonId equals peo.Id
select new FullNameStudentViewModel
{
Id = stu.Id,
FullName = peo.FirstName + " " + peo.LastName
}).ToList();
使用以下查询:
var query =
from exams in _context.Exams
from students in exams.Class.Students
join people in _context.People on students.PersonId equals people.Id
where exams.Id == id
select new
{
Id = students.Id,
FullName = people.FirstName + " " + people.LastName
};
我需要使用多个连接进行查询,其中包括从多对多关系生成的连接table。如果我直接查询数据库,它会工作,但我需要在我的一个控制器中进行查询,因为我没有 join-table 的模型,我无法进行简单的连接一个 DbSet,我已经被困了几个小时试图找出它是如何工作的。
这是我在数据库中的表:
考试
- (PK) 身份证
- (FK) ClassId
关系:* 到 1
类
- (PK) 身份证
关系:1 到 *
类学生
- (PK) ClassId
- (PK) 学号
关系:* 到 1
学生
- (PK) 身份证
- (FK) PersonId
关系:1 对 1
人
- (PK) 身份证
- 名字
- 姓氏
这些是我的模型:
public class Exam
{
public int Id { get; set; }
public short ClassId { get; set; }
public Class Class { get; set; }
}
public class Class
{
public Class()
{
this.Students = new HashSet<Student>();
}
public int Id { get; set; }
public virtual ICollection<Student> Students { get; set; }
}
public class Student
{
public Student()
{
this.Classes = new HashSet<Class>();
}
public int Id { get; set; }
public virtual ICollection<Class> Classes { get; set; }
}
public class Person
{
public int Id { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
}
我正在尝试获取此查询...
SELECT stu.Id, peo.FirstName, peo.LastName
FROM Exams AS exa
JOIN Classes AS cla
ON cla.Id = exa.ClassId
JOIN ClassesStudents AS clastu
ON clastu.ClassId = cla.Id
JOIN Students AS stu
ON stu.Id = clastu.StudentId
JOIN People AS peo
ON peo.Id = stu.PersonId
WHERE exa.Id = 1;
... 在我的 Controller 中有点像这样工作:
public ActionResult CreateMark(int id)
{
var students = (from exams in _context.Exams
join classes in _context.Classes
on exams.ClassId equals classes.Id
join classesstudents in _context.ClassesStudents // that
on classes.Id equals classesstudents.ClassId // part
join students in _context.Students // doesn't
on classesstudents.StudentId equals students.Id // work
join people in _context.People
on students.PersonId equals people.Id
where exams.Id == id
select new
{
Id = students.Id,
FullName = people.FirstName + " " + people.LastName
}).ToList();
如果有任何帮助,我将不胜感激!
编辑:
我设法让它与以下代码一起工作,但是有没有一种方法可以在一次查询中使用更少的代码来完成它?
public ActionResult Create(int id)
{
var class = (from exa in _context.Exams
join cla in _context.Classes
on exa.ClassId equals cla.Id
where exa.Id == id
select new
{
ClassId = cla.Id,
Students = cla.Students
}).ToList();
var classWithStudents= (from cla in class
from stu in cla.Students
select new
{
Id = stu.Id,
PersonId = stu.PersonId
}).ToList();
var students = (from stu in classWithStudents
join peo in _context.People
on stu.PersonId equals peo.Id
select new FullNameStudentViewModel
{
Id = stu.Id,
FullName = peo.FirstName + " " + peo.LastName
}).ToList();
使用以下查询:
var query =
from exams in _context.Exams
from students in exams.Class.Students
join people in _context.People on students.PersonId equals people.Id
where exams.Id == id
select new
{
Id = students.Id,
FullName = people.FirstName + " " + people.LastName
};