initialiseurs d'objets dans une requête LINQ - est-il possible de réutiliser les données calculées?

StackOverflow https://stackoverflow.com/questions/6331913

  •  27-10-2019
  •  | 
  •  

Question

J'utilise un quelque chose comme la suivante requête LINQ qui semble (après une certaine simplification):

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
};

Ce qui me dérange est l'expression de calcul qui apparaît deux fois, pour PassedUsersNum et CompletionRate.

En supposant que CompletionRate = (PassedUsersNum / TotalUsersNum) * 100, comment puis-je écrire en réutilisant le calcul de PassedUsersNum, au lieu d'écrire à nouveau cette expression?

Était-ce utile?

La solution

La façon la plus simple serait d'utiliser let pour injecter une nouvelle étape de sélection d'abord:

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
    };

L'expression ne sera évaluée une fois par groupe, bien sûr.

Autres conseils

Vous pouvez également extraire seulement votre comte func dans une autre méthode qui retourne un Func si vous voulez, ou une méthode qui prend un double et retourne un 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 */ }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top