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

问题描述 投票:-1回答:1

我有AssessmentItems DB对象,其中包含以下项目:哪个用户评估(EvaluatorId),哪个提交(SubmissionId),基于哪个专栏项目(或条件)(RubricItemId)和何时( DateCreated)。

我将此对象按RubricItemIdDateCreated分组,以根据每个评估标准(或专栏项目)计算一些每日统计数据。

例如,我计算了AverageScore,它可以正常工作并返回类似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对象并再次计算这些属性:

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

 }

但是,这非常昂贵。我想知道是否可以对代码进行一些调整以实现此目标,还是应该从头开始使用另一种方法。

c# linq group-by linq-to-entities
1个回答
0
投票
如果将查询分为两半,则可以根据需要计算平均值(我也根据相同的标准计算了NumberOfStudentsEvaluating),但是我不确定EF / EF Core是否能够转换为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 .Select(rig => new { RubricItemId = rig.Key, DatesCreated = rig.Select(ai => ai.DateCreated).Distinct(), Items = rig }) .SelectMany(g => g.DatesCreated.Select(d => new { g.RubricItemId, d, Items = g.Items.Where(b => b.DateCreated <= d) })) .Select(g => new { g.RubricItemId, DateCreated = g.d.ToShortDateString(), //.ToString(@"yyyy-MM-dd"), AverageScore = g.Items.Average(ai => ai.CurrentScore), NumberOfStudentsEvaluating = g.Items.Select(ai => ai.EvaluatorId).Distinct().Count(), }).ToList();

© www.soinside.com 2019 - 2024. All rights reserved.