我正在使用一个linq查询,它看起来(在一些简化之后)类似于以下内容:
List<UserExams> listUserExams = GetUserExams();
var examData =
from userExam in listUserExams
group by userExam.ExamID into groupExams
select new ExamData()
{
ExamID = groupExams.Key,
AverageGrade = groupExams.Average(e => e.Grade),
PassedUsersNum = groupExams.Count(e => /* Some long and complicated calculation */),
CompletionRate = 100 * groupExams.Count(e => /* The same long and complicated calculation */) / TotalUsersNum
};
困扰我的是对PassedUsersNum和CompletionRate两次出现的计算表达式。
假设CompletionRate = (PassedUsersNum / TotalUsersNum) * 100
,如何通过重用PassedUsersNum的计算来编写它,而不是再次编写该表达式?
答案 0 :(得分:6)
最简单的方法是先使用let
注入另一个选择步骤:
List<UserExams> listUserExams = GetUserExams();
var examData =
from userExam in listUserExams
group by userExam.ExamID into groupExams
let passCount = groupExams.Count( /* long expression */)
select new ExamData()
{
ExamID = groupExams.Key,
AverageGrade = groupExams.Average(e => e.Grade),
PassedUsersNum = passCount,
CompletionRate = 100 * passCount / TotalUsersNum
};
当然,每个组只会评估一次表达式。
答案 1 :(得分:1)
你也可以将你的Count func提取到另一个方法中,如果你想要的话,它会返回一个Func,或者一个带有double的方法并返回一个bool。
List<UserExams> listUserExams = GetUserExams();
var examData =
from userExam in listUserExams
group by userExam.ExamID into groupExams
select new ExamData()
{
ExamID = groupExams.Key,
AverageGrade = groupExams.Average(funcMethod()),
PassedUsersNum = groupExams.Count(e => traditionalMethod(e)),
CompletionRate = 100 * groupExams.Count(e => /* The same long and complicated calculation */) / TotalUsersNum
};
// later...
private Func<double,bool> funcMethod(){ return e=> /* your calculation */ }
private bool traditionalMethod(double d){ return /* your calculation */ }