【问题标题】:Sum of child of child in LINQLINQ中孩子的孩子总和
【发布时间】:2016-02-28 10:33:39
【问题描述】:

我需要 EF6 中的 LINQ 查询方面的帮助。

主表称为EXAM。它的孩子是ExamResult。 每个ExamResult 都有一个Question 和选定的Answer。 每个Answer 都有power(0 表示错误,1 表示正确)。 如果我想知道正确答案的总数,我只需运行命令:

var examTotal = db.Exams.FirstOrDefault(ex => ex.ExamID == examId).ExamResults.Sum(er => er.Answer.Power);

我的问题是当一些问题没有得到回答时,我得到了NullReferenceException。

【问题讨论】:

    标签: c# entity-framework linq master-detail


    【解决方案1】:

    你的“命令”有几个问题。

    首先,至少有 两个 查询:

    (1)var exam = db.Exams.FirstOrDefault(ex => ex.ExamID == examId);

    (2)var examTotal = exam.ExamResults.Sum(er => er.Answer.Power);

    请注意,第二个确实在 LINQ to Objects 上下文中执行(由于延迟加载,最终包括一些隐藏的数据库调用)。 在这种情况下,有 2 个可能的地方可以提高 NRE

    (A) exam.ExamResults 如果exam 为空
    (B)er.Answer.Power如果er.Answer为空

    您可以通过包含其他答案中建议的空检查来修复它们。

    但更好的方法是让您的命令在 LINQ to Entities 上下文中执行单个查询,其中导航属性具有不同的含义:

    var examTotal = db.Exams.Where(ex => ex.ExamID == examId)
        .SelectMany(ex => ex.ExamResults)
        .Sum(er => (int?)er.Answer.Power) ?? 0;
    

    唯一需要的技巧是将要求和的字段投影为 可为空 类型(我使用 int? 假设 Power 字段是 int 类型,更改它如果不同,请根据您的类型)。这让 EF 始终返回 Sum,无论 er.Answer 为 null 还是 ex.ExamResults 为空。

    【讨论】:

      【解决方案2】:

      一些通用的空检查应该可以解决问题

      var exam = db.Exams.FirstOrDefault(ex => ex.ExamID == examId);
      var examTotal = exam.ExamResults.Sum(er => er.Answer?.Power ?? 0);
      

      ...如果您不使用 C# 6,这里是它的另一个版本:

      var exam = db.Exams.FirstOrDefault(ex => ex.ExamID == examId);
      var examTotal = exam.ExamResults.Sum(er => er.Answer != null ? er.Answer.Power : 0);
      

      【讨论】:

        【解决方案3】:

        试试这个:

        var examTotal = db.Exams.FirstOrDefault(ex => ex.ExamID == examId).ExamResults.Where(er => er.Answer != null).Sum(er => er.Answer.Power);
        

        【讨论】:

          【解决方案4】:

          这应该可行:

          var examTotal = db.Exams.FirstOrDefault(ex => ex.ExamID == examId).ExamResults.Count(er => er.Answer.Power == 1);
          

          这不会使用该值,而是查看它是否等于 1,因此不会生成任何NullReferenceException。

          【讨论】:

          • 我肯定会得到NullReferenceException,因为空值是有答案的,而不是有答案的权力。换句话说,我可能有一个没有答案的问题,但如果有答案,我就没有权力没有答案。
          • @omarmallat 抱歉,错过了 Answer 为空的情况......我太愚蠢了......
          猜你喜欢
          • 1970-01-01
          • 2014-10-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-09-27
          • 2017-01-25
          相关资源
          最近更新 更多