如何使用 linq 或 sql 获取仅在选定批次中的学生

本文关键字:linq 何使用 sql 获取 | 更新日期: 2023-09-27 18:33:07

我的数据库中有Students,Batches和StudentBatches表。学生和相应的批次将出现在学生批次表中,如下所示。

学生

ID   Name
1   Student'A'
2   Student'B'
3   Student'C'
4   Student'D'
5   Student'E'

批次

ID   Name
1   Batch'A'
2   Batch'B'
3   Batch'C'

学生批次

ID StudentID BatchID
1      1        1
2      2        2
3      2        3
4      3        3
5      4        3
6      5        2

我的要求是,当我提供任何批次 ID 时,我应该得到仅在该批次中存在的学生。例如,如果我给批次 ID 3,那么我应该得到 3,4 个学生 ID,因为它们在任何其他批次中都不存在,我不应该得到 2 个学生 ID,因为该学生也在批次 2 中。

我已经在 linq 中编写了此查询。

from batch_student in context.Student_batches
                    group batch_student by batch_student.SID into new_batch_student
                    join student in context.Students on new_batch_student.Key equals student.Id
                    where new_batch_student.Count() == 1 && new_batch_student.Any(x => x.BID == 3)
                    select student;

查询正在工作。但这会对性能产生任何影响吗?是否有任何查询可以获取所需的结果?

如何使用 linq 或 sql 获取仅在选定批次中的学生

另一种选择是摆脱分组并添加子查询

  var query = from batch in context.Student_batches
              join student in context.Students on batch.SID equals student.Id
              where batch.BID == 3 && 
                    !context.Student_batches.Any(x => x.SID == student.Id && x.BID != batch.BID)
              select student;

见小提琴

这是一个简单的方法:

var batchID = 3;
var goodStudentIDs = context.Student_batches
    .Where(i => i.BatchID == batchID)
    .Select(i => i.StudentID);
var badStudentIDs = context.Student_batches
    .Where(i => i.BatchID != batchID)
    .Select(i => i.StudentID);
var studentIDs = goodStudentIDs.Except(badStudentIDs);
var students = context.Students.Where(i => studentIDs.Contains(i.ID));

如果您愿意,您可以将这四个语句合并为一个语句:

var batchID = 3;
var students = context.Students
    .Where(i => context.Student_batches
    .Where(j => j.BatchID == batchID)
    .Select(j => j.StudentID)
    .Except(context.Student_batches
    .Where(j => j.BatchID != batchID)
    .Select(j => j.StudentID))
    .Contains(i.ID));