如何使用EF Core关联两张表统计用户的考试参加次数
实现逻辑
- 先统计TableB中总题数,由于每道题对应2条TableA答题记录,单次完整考试对应的TableA记录数为
总题数 * 2 - 统计对应用户的有效答题总条数,过滤掉不属于本次考试试题的记录
- 用有效答题总条数除以单次考试的记录数,整数除法得到的结果就是完成的考试次数
代码实现
分步查询(可读性更高)
// 第一步:获取考试总题数 int totalQuestionCount = await _dbContext.TableB.CountAsync(); int perExamRecordCount = totalQuestionCount * 2; // 替换为实际要查询的用户ID,TableA中存储用户ID的字段为UserId int targetUserId = 1; // 第二步:统计该用户的有效答题记录数 int userValidAnswerCount = await _dbContext.TableA .Where(a => a.UserId == targetUserId && _dbContext.TableB.Select(b => b.QuestionID).Contains(a.QuestionID)) .CountAsync(); // 第三步:计算完成的考试次数,整数除法自动舍弃未完成的考试记录 int finishedExamCount = userValidAnswerCount / perExamRecordCount;
单查询写法(减少数据库交互次数)
int targetUserId = 1; int finishedExamCount = await _dbContext.TableA .Where(a => a.UserId == targetUserId) .GroupBy(a => a.UserId) .Select(g => g.Count() / (_dbContext.TableB.Count() * 2)) .FirstOrDefaultAsync();
注意事项
- 如果你的表结构中存在考试批次ID(ExamAttemptId)字段,直接按用户ID+批次ID分组统计去重后的数量即可,准确性更高
- 以上写法所有逻辑都会翻译成SQL在数据库端执行,相比你原来先拉取所有QuestionID到内存的写法,性能更好,也不会受题量大小影响
内容的提问来源于stack exchange,提问作者user3559195
相关产品推荐
相关产品推荐

