使用LINQ计算含正负数值列的负数平均值并解决相关LINQ报错
错误原因及解决方案
1. 首先排查基础语法错误
你贴的完整代码中该行写的是allstock.AbovePmHigh - Math.Round((decimal)stocks.Where(x => x.PmHighvHigh<0).Average());,这里错误使用了减号-而非赋值运算符=,直接会触发编译错误,先修正为=。
2. 运行时报错的核心原因
你当前的写法如果筛选后没有符合条件的负数,Average()方法会直接抛出InvalidOperationException异常,原因是空序列无法计算平均值;如果PmHighvHigh是可空数值类型(比如decimal?/int?),未处理空值也会触发报错。
3. 正确实现代码
写法1:显式判断空序列(可读性更高)
// 先筛选所有PmHighvHigh为负数的条目,加载到列表 var negativeItems = stocks.Where(x => x.PmHighvHigh < 0).ToList(); if (negativeItems.Any()) { allstock.AbovePmHigh = Math.Round(negativeItems.Average(x => x.PmHighvHigh)); } else { // 无符合条件的负数时,根据业务需求设置默认值,示例为0 allstock.AbovePmHigh = 0; }
写法2:链式调用简化写法
allstock.AbovePmHigh = Math.Round( stocks.Where(x => x.PmHighvHigh < 0) .Select(x => x.PmHighvHigh) .DefaultIfEmpty(0) // 空序列时默认返回0,避免Average报错 .Average() );
若PmHighvHigh是可空类型,额外过滤空值:
allstock.AbovePmHigh = Math.Round( stocks.Where(x => x.PmHighvHigh.HasValue && x.PmHighvHigh.Value < 0) .Select(x => x.PmHighvHigh.Value) .DefaultIfEmpty(0) .Average() );
注意事项
- 不需要强制转换
Average()的返回值为decimal,如果PmHighvHigh本身是数值类型,Average()返回的类型和字段类型匹配,Math.Round可直接处理。 - 如果
stocks是EF的IQueryable类型(未加载到内存),上述写法可直接翻译为SQL执行,不会产生性能问题。
内容的提问来源于stack exchange,提问作者F.OLeary
相关产品推荐
相关产品推荐

