我有以下语句,其中使用GroupBy
计算最大值,并且使用Any()
事先检查是否有任何记录,但是此查询仍然返回Sequence contains no elements exception
错误。有什么想法吗?
baseQuery = baseQuery.Where(s => s.LearningActions.SelectMany(la => la.ProgressUpdates)
.GroupBy(d => d.LearningActionId)
.Select(a => a.Any() ? new { Max = a.Max(d => d.Progress) } : new { Max = 0})
.Average(d => d.Max) < averageProgress.GetValueOrDefault());
仅在需要的情况下是baseQuery
IQueryable<Submission> baseQuery = _context.Submissions
.Where(s => s.ReviewRoundId == reviewRoundId);
我还尝试了以下方法:
baseQuery = baseQuery.Where(s => s.LearningActions.SelectMany(la => la.ProgressUpdates)
.GroupBy(d => d.LearningActionId)
.Select(a => new { Max = (int?) a.Max(d => d.Progress) })
.Average(a => a.Max.GetValueOrDefault()) < averageProgress.GetValueOrDefault());
但是它抛出:
查询源(来自[a]中的LearningActionProgress d)已与表达式关联。
更新
以下代码有效:
baseQuery = baseQuery.Where(s => s.LearningActions.SelectMany(la => la.ProgressUpdates)
.GroupBy(d => d.LearningActionId)
.Select(a => a.Max(d => d.Progress)).Any() ?
s.LearningActions.SelectMany(la => la.ProgressUpdates)
.GroupBy(d => d.LearningActionId)
.Select(a => a.Max(d => d.Progress)).Average() > averageProgress.GetValueOrDefault() : false); // Here a can be null or empty
我不得不把这张支票s.LearningActions.SelectMany(la => la.ProgressUpdates).GroupBy(d => d.LearningActionId).Select(a => a.Max(d => d.Progress)).Any()
但是,我认为这有点多余,如何更好地包含此check
?
答案 0 :(得分:1)
您的问题是.Average(a => a.Max)
。 a可以为null或为空。您必须检查它:
IEnumerable<Submission> baseQuery = new List<Submission>()
{
new Submission()
{
LearningActions = new List<LearningAction>()
{
//new LearningAction() { ProgressUpdates = null }, // will throw nullRef
new LearningAction() { ProgressUpdates = new List<ProgressUpdate>() }, // this is your problem
},
}
};
int? averageProgress = 100;
baseQuery = baseQuery.Where(
s => s.LearningActions.SelectMany(la => la.ProgressUpdates)
.GroupBy(d => d.LearningActionId)
.Select(a => a.Any() ? new { Max = a.Max(d => d.Progress) } : new { Max = 0 })
.Average(a => a?.Max) < averageProgress.GetValueOrDefault()); // Here a can be null or empty
// For Expressions use Any again:
// .Average(a => a.Any() ? a : 0) < averageProgress.GetValueOrDefault());
Console.WriteLine(string.Join("\n\n", baseQuery));
如果要使用此代码,可以将其缩短一点。您不需要匿名类:
baseQuery = baseQuery.Where(
s => s.LearningActions.SelectMany(la => la.ProgressUpdates)
.GroupBy(d => d.LearningActionId)
.Select(a => a?.Max(d => d.Progress)) // select the "int?"
.Average() < averageProgress.GetValueOrDefault()); // Average can be performed on the resulting IEnumerable<int?>
答案 1 :(得分:1)
您可以使用DefaultIfEmpty创建一个合理的默认对象吗?
baseQuery = baseQuery.Where(s => s.LearningActions.SelectMany(la => la.ProgressUpdates)
.GroupBy(d => d.LearningActionId)
.Select(a => a.Any() ? new { Max = a.Max(d => d.Progress) } : new { Max = 0})
.DefaultIfEmpty(defaultItem)
.Average(d => d.Max) < averageProgress.GetValueOrDefault());