C# LINQ中的子项之和
我需要EF6中LINQ查询的帮助 主表称为C# LINQ中的子项之和,c#,entity-framework,linq,master-detail,C#,Entity Framework,Linq,Master Detail,我需要EF6中LINQ查询的帮助 主表称为EXAM。它的子级是ExamResult。 每个ExamResult都有一个问题和所选的答案。 每个答案都有电源(错误为0,正确为1)。 如果我想知道正确答案的总数,我只需运行以下命令: var examTotal = db.Exams.FirstOrDefault(ex => ex.ExamID == examId).ExamResults.Sum(er => er.Answer.Power); 我的问题是当一些问题没有得到回答时,我得到
EXAM
。它的子级是ExamResult
。
每个ExamResult
都有一个问题
和所选的答案
。
每个答案
都有电源
(错误为0,正确为1)。
如果我想知道正确答案的总数,我只需运行以下命令:
var examTotal = db.Exams.FirstOrDefault(ex => ex.ExamID == examId).ExamResults.Sum(er => er.Answer.Power);
我的问题是当一些问题没有得到回答时,我得到了NullReferenceException
这应该有效:
var examTotal = db.Exams.FirstOrDefault(ex => ex.ExamID == examId).ExamResults.Count(er => er.Answer.Power == 1);
这将不使用该值,而是查看它是否等于1,因此不会生成任何NullReferenceException
这应该可以工作:
var examTotal = db.Exams.FirstOrDefault(ex => ex.ExamID == examId).ExamResults.Count(er => er.Answer.Power == 1);
这将不使用该值,而是查看它是否等于1,因此不会生成任何NullReferenceException
尝试以下操作:
var examTotal = db.Exams.FirstOrDefault(ex => ex.ExamID == examId).ExamResults.Where(er => er.Answer != null).Sum(er => er.Answer.Power);
试试这个:
var examTotal = db.Exams.FirstOrDefault(ex => ex.ExamID == examId).ExamResults.Where(er => er.Answer != null).Sum(er => er.Answer.Power);
一些常规的空值检查应该可以做到这一点
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);
一些常规的空值检查应该可以做到这一点
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);
您的“命令”有几个问题 首先,至少有两个查询: (1)
var-exam=db.Exams.FirstOrDefault(ex=>ex.ExamID==ExamID)代码>
(2) var examTotal=exam.ExamResults.Sum(er=>er.Answer.Power)代码>
请注意,第二个确实在LINQtoObjects上下文中执行(最终包括一些由于延迟加载而隐藏的db调用)。
在这种情况下,有两个可能的地方可以提高NRE
(A) exam.ExamResultsifexam
为空
(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;
唯一需要的技巧是将要求和的字段投影为可为null的类型(我使用了int?
假设Power
字段为int
类型,如果不同,请将其更改为您的类型)。这使得EF总是返回和
,而不管er.Answer
是空的还是ex.ExamResults
是空的。您的“命令”有几个问题
首先,至少有两个查询:
(1) var-exam=db.Exams.FirstOrDefault(ex=>ex.ExamID==ExamID)代码>
(2) var examTotal=exam.ExamResults.Sum(er=>er.Answer.Power)代码>
请注意,第二个确实在LINQtoObjects上下文中执行(最终包括一些由于延迟加载而隐藏的db调用)。
在这种情况下,有两个可能的地方可以提高NRE
(A) exam.ExamResultsifexam
为空
(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;
唯一需要的技巧是将要求和的字段投影为可为null的类型(我使用了int?
假设Power
字段为int
类型,如果不同,请将其更改为您的类型)。这使得EF总是返回和
,而不管er.Answer
是空的还是ex.ExamResults
是空的。我肯定会得到NullReferenceException
,因为空是有答案,而不是有答案的能力。换句话说,我可能有一个没有答案的问题,但如果回答了,我就不能有一个没有权力的答案。@Omarmalat抱歉,没有注意到answer
为空的情况。。。。我真是太蠢了。我肯定会得到NullReferenceException
,因为NullReferenceException就是有答案,而不是有答案的能力。换句话说,我可能有一个没有答案的问题,但如果回答了,我就不能有一个没有权力的答案。@Omarmalat抱歉,没有注意到answer
为空的情况。。。。我真蠢。。