C#中通过Lambda表达式按ID获取实体对象及按问题级别计算得分
解决方案
这个需求完全可行,你可以通过实体的导航属性直接关联获取Question的LevelId,替换掉硬编码逻辑,具体实现如下:
1. 确保加载关联的Question数据
如果你的GetUserQuestionHistory仓储方法没有自动加载Alternative.Question导航属性,需要修改方法,添加Include语句(以EF Core为例):
public IQueryable<UserQuestionHistory> GetUserQuestionHistory(string userId) { return _context.UserQuestionHistories .Include(uqh => uqh.Alternative) .ThenInclude(a => a.Question) // 加载关联的Question实体 .Where(uqh => uqh.UserId == userId); }
2. 按级别分组计算总分
修改得分计算逻辑,筛选答对的记录后按LevelId分组,再匹配对应分值计算:
// 定义级别与分值的映射,也可放到配置文件中 var levelScoreMap = new Dictionary<int, int> { { 1, 2 }, { 2, 3 }, { 3, 5 } }; userScoreDto.UserScore = history .Where(c => c.Alternative.IsCorrectAlternative) // 仅保留答对的记录 .GroupBy(c => c.Alternative.Question.LevelId) // 按题目级别分组 .Sum(g => g.Count() * levelScoreMap.GetValueOrDefault(g.Key, 0)); // 计算每组得分并求和
补充说明
- 利用
Alternative中的virtual Question Question导航属性,EF会自动关联查询对应的Question数据,直接获取LevelId,无需手动通过QuestionId单独查询。 - 使用字典存储级别分值映射,后续新增或修改级别分值时只需调整字典,不用修改核心计算逻辑,扩展性更强。
- 如果不想用字典,也可以用switch表达式实现:
userScoreDto.UserScore = history .Where(c => c.Alternative.IsCorrectAlternative) .GroupBy(c => c.Alternative.Question.LevelId) .Sum(g => g.Count() * (g.Key switch { 1 => 2, 2 => 3, 3 => 5, _ => 0 // 其他级别默认0分,可按需调整 }));
内容的提问来源于stack exchange,提问作者Julia_Gubolin
相关产品推荐
相关产品推荐

