如何在EF Core中实现SQL NOT IN逻辑 排除已签到学生生成签到按钮
现有代码的核心问题
- 最终传入按钮生成方法的是未经过滤的完整团队学生集合,你之前写的未签到筛选逻辑完全没有用上
- 筛选逻辑对象错误:你是要从「团队学生集合」中排除已签到学生,而不是从「学生会话集合」中筛选
- 字段匹配错误:筛选
studentsnotArrvied时用SessionStudent的主键Id和已签到学生ID做匹配,应该用SessionStudent.StudentId字段 - 缺少当前会话过滤:没有限定只匹配本次会话的签到记录,会把学生在其他历史会话的签到记录也纳入判断逻辑
修正后的代码
第一步:调整筛选逻辑,过滤得到未签到学生
var studentsForTeam = await api.GetAllStudentsByTeamId(item.TeamId); SessionId = item.Id; TeamId = item.TeamId; List<SessionStudent> allSessionStudents = await api.GetALLStudentsSessions(); // 提取当前会话下已签到(非缺勤+已到场)的学生ID集合,转HashSet提升匹配性能 var attendedStudentIds = allSessionStudents .Where(x => x.SessionId == SessionId // 仅匹配当前会话的签到记录 && x.isAbesent == false && x.isArrived == true) .Select(x => x.StudentId) .ToHashSet(); // 等效SQL NOT IN逻辑:从团队学生中排除已签到的学生 var notAttendedStudents = studentsForTeam .Where(student => !attendedStudentIds.Contains(student.StudentId)) .ToList(); // 传入过滤后的未签到学生生成按钮 CheckInButtonsStudents(new ObservableCollection<Student>(notAttendedStudents));
第二步:修正按钮生成方法的隐藏问题
你原方法中AutomationId赋值错误,没有取当前遍历学生的ID,修正对应代码行即可:
var btn = new Button() { AutomationId = item.StudentId.ToString(), // 修正此处,取当前学生的ID BackgroundColor = Color.Blue, TextColor = Color.White, Text = item.FirstName + " " + item.Surname, };
可选优化
如果你可以修改API的底层EF Core查询逻辑,可以把两次接口请求合并为单次关联查询,直接在数据库层面完成NOT IN过滤,减少数据传输和内存消耗,性能更好。
内容的提问来源于stack exchange,提问作者dotnetdevcsharp
相关产品推荐
相关产品推荐

