使用 GroupBy 计算平均值或根据整个数据计数直到相应日期

Using GroupBy to compute average or count based on the whole data until the corresponding date

我有 AssessmentItems 数据库 object,其中包含以下项目:哪个用户评估 (EvaluatorId),哪个提交 (SubmissionId),基于哪个评分项目(或标准)(RubricItemId)和何时(DateCreated)。

我将此 object 按 RubricItemIdDateCreated 分组,以根据每个评估标准(或标题项)计算一些日常统计数据。

例如,我计算了 AverageScore,它工作正常并且 returns 输出如:RubricItem: 1, Day: 15/01/2019, AverageScore: 3.2

_context.AssessmentItems
        .Include(ai => ai.RubricItem)
        .Include(ai => ai.Assessment)
        .Where(ai => ai.RubricItem.RubricId == rubricId && ai.Assessment.Submission.ReviewRoundId == reviewRoundId)
        .Select(ai => new
        {
            ai.Id,
            DateCreated = ai.DateCreated.ToShortDateString(),//.ToString(@"yyyy-MM-dd"),
            ai.CurrentScore,
            ai.RubricItemId,
            ai.Assessment.SubmissionId,
            ai.Assessment.EvaluatorId

        })
        .GroupBy(ai => new { ai.RubricItemId, ai.DateCreated })
        .Select(g => new
        {
            g.Key.RubricItemId,
            g.Key.DateCreated,
            AverageScore = g.Average(ai => ai.CurrentScore),
            NumberOfStudentsEvaluating = g.Select(ai => ai.EvaluatorId).Distinct().Count(),

        }).ToList();

我想做的是计算直到那一天的平均值。我的意思是不计算当天的平均值,而是想得到直到那一天的平均值(也就是说,我想考虑前几天的评估分数)。同样的原因,当我计算 NumberOfStudentsEvaluating 时,我想指出直到那天参加评估的学生总数。

实现此目的的一种方法是遍历 result object 并再次计算这些属性:

 foreach (var i in result)
 {
     i.AverageScore = result.Where(r => r.DateCreated <= i.DateCreated).Select(r => r.AverageScore).Average(),

 }

但是,这是相当昂贵的。我想知道是否可以稍微调整代码来实现这一点,或者我应该从头开始使用另一种方法。

如果将查询分成两半,您可以根据需要计算平均值(我也根据相同的条件计算了 NumberOfStudentsEvaluating)但我不确定 EF/EF 核心将能够翻译成 SQL:

var base1 = _context.AssessmentItems
    .Include(ai => ai.RubricItem)
    .Include(ai => ai.Assessment)
    .Where(ai => ai.RubricItem.RubricId == rubricId && ai.Assessment.Submission.ReviewRoundId == reviewRoundId)
    .Select(ai => new {
        ai.Id,
        ai.DateCreated,
        ai.CurrentScore,
        ai.RubricItemId,
        ai.Assessment.SubmissionId,
        ai.Assessment.EvaluatorId

    })
    .GroupBy(ai => ai.RubricItemId);

var ans1 = base1
            .SelectMany(rig => rig.Select(ai => ai.DateCreated).Distinct().Select(DateCreated => new { RubricItemId = rig.Key, DateCreated, Items = rig.Where(b => b.DateCreated <= DateCreated) }))
            .Select(g => new {
                g.RubricItemId,
                DateCreated = g.DateCreated.ToShortDateString(), //.ToString(@"yyyy-MM-dd"),
                AverageScore = g.Items.Average(ai => ai.CurrentScore),
                NumberOfStudentsEvaluating = g.Items.Select(ai => ai.EvaluatorId).Distinct().Count(),
            }).ToList();