从3个表中获取数据的LINQ查询



我使用的是SQL Server 2017, . net 4.5和EF core。

我有以下表:Student_Course:有Student_Id, Course_ID和Student_Course_ID - pk.

学生:First_Name, Last_Name, Email, Student_ID - PK课程:Id pk,名称

我正在尝试检索学生的列表与他们各自的课程。我还需要每个学生的课程数。

对于上面提到的表,我在c#中有以下实体Student_Course:具有学生和课程列表的导航属性学生:课程:

我正在尝试使用LINQ:

进行此查询控制器:

public IList<StudentCourse> GetStudents()
{
Student_CourseContext scContext = new Student_CourseContext();

var studentCourses = (from sc in scContext.Student_Course
from student in sc.Students.Where( x => x.Student_ID == 
sc.Student_ID) 
from course in sc.Courses.Where (x => x.ID == sc.Course_ID)
where sc.Student_ID == student.Student_ID
&& sc.Course_ID == course.ID
&& student.First_Name != "None"
//join course in sc.Courses
//from sc in studentCourseEntity.Student_Courses.GroupBy( x => x.Student_ID)
select new StudentCourse
{
StudentName = student.First_Name + ' ' + student.Last_Name,
//CourseCount = sc.Gr,
Course = string.Join(",", course.Name)
}).ToList();
return studentCourses.ToList();
}

}

返回如下查询:

SELECT ([s0].[First_Name] + CAST(N' ' AS nvarchar(max))) + [s0].[Last_Name], [c].[Name]
FROM [Student_Course] AS [s]
INNER JOIN [Student] AS [s0] ON ([s].[Student_Course_ID] = [s0].[Student_Course_ID]) AND ([s].[Student_ID] = [s0].[Student_ID])
INNER JOIN [Course] AS [c] ON ([s].[Student_Course_ID] = [c].[Student_Course_ID]) AND ([s].[Course_ID] = [c].[ID])
WHERE (([s].[Student_ID] = [s0].[Student_ID]) AND ([s].[Course_ID] = [c].[ID])) AND (([s0].[First_Name] <> N'None') OR [s0].[First_Name] IS NULL)

不是连接指定的列,而是连接Student_Course表的主键STudent_Course_ID。由于这个连接,我得到错误:

列名'Student_Course_ID'无效。列名'Student_Course_ID'无效。

,因为Student和Course表没有这个字段。请让我知道该怎么做。

我试过模式。方法来定义两者之间的关系这些表,但我能够在Student, Student_Course和当然表。

提前感谢。

所以您需要每个学生的姓名和他所参加的所有课程的名称列表(集合?)

var studentsWithTheCoursesTheyAttend = dbContext.Students
.Select(student => new
{
Name = student.First_Name + ' ' + student.Last_Name,
Courses = dbContext.Student_Course
.Where(studentCourse => studentCourse.StudentId == student.Id)
.Select(studentCourse => dbContext.Courses
.Where(course => course.Id == studentCourse.CourseId)
.Select(course => course.Name)
.FirstOrDefault())
.ToList(),                    
}

说明:从学生完整表中的每个学生中取他的名字:

... = dbContext.Students
.Select(student => new
{
Name = student.First_Name + ' ' + student.Last_Name,

还选择该学生的所有Student_Courses(=所有具有外键studententid等于该学生的主键的Student_Courses):

Courses = dbContext.Student_Course
.Where(studentCourse => studentCourse.StudentId == student.Id)

从该学生的每个选定的Student_Course中,您希望获得该Student_Course引用的课程的名称。为此,我们将首先获得主键等于外键StudentCourse的所有课程。CourseId:

.Select(studentCourse => dbContext.Courses
.Where(course => course.Id == studentCourse.CourseId)

我们不需要完整的课程,我们只需要它的名称:

.Select(course => course.Name)

我们知道每个studentCourse都只有一个它所引用的Course,不等于0,也不大于1。毕竟,外键studentCourse.CourseId只指向一个Course。

因此我们只需要取第一个。我本可以使用First(),但是在IQueryable报告问题时使用First,因此我使用FirstOrDefault()

.FirstOrDefault(),

所以到现在为止,我从每一个学生那里都知道了他的名字,以及他参加的所有课程的名称。将此设置为课程列表:

Courses = ...
.ToList(),

现在你有了这样的东西:

{
Name = "Sukumar Krishnamurthy",
Courses =
{
"Advanced .NET",
"All aspects of LINQ",
"Ups and downs of C#",
},
},
{
Name = "Harald Coppoolse",
Courses =
{
"Windows Services",
"REST in a proper manner",
},
},

属性Courses是学生参加的课程名称列表。列表的长度代表参加课程的数量。

如果需要,您可以将课程列表转换为一个带有名称的字符串。但是我不确定这会提高可读性:

"Windows Services REST in a proper manner"

最新更新