使用 GroupBy 计算平均值或根据整个数据计数直到相应日期
Using GroupBy to compute average or count based on the whole data until the corresponding date
我有 AssessmentItems
数据库 object,其中包含以下项目:哪个用户评估 (EvaluatorId
),哪个提交 (SubmissionId
),基于哪个评分项目(或标准)(RubricItemId
)和何时(DateCreated
)。
我将此 object 按 RubricItemId
和 DateCreated
分组,以根据每个评估标准(或标题项)计算一些日常统计数据。
例如,我计算了 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();
我有 AssessmentItems
数据库 object,其中包含以下项目:哪个用户评估 (EvaluatorId
),哪个提交 (SubmissionId
),基于哪个评分项目(或标准)(RubricItemId
)和何时(DateCreated
)。
我将此 object 按 RubricItemId
和 DateCreated
分组,以根据每个评估标准(或标题项)计算一些日常统计数据。
例如,我计算了 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();