繁体   English   中英

无序列的 EF Core 平均值

[英]EF Core Average with no sequence

当从 List 想要按属性进行分组并取特定属性的平均值或总和时,我遇到了问题,我收到错误序列不包含元素。 比我把 DefaultIfEmpty,比我得到不同的错误NullReferenceException: Object reference not set to an instance of an object。

代码是这样的:

var items = _repository.GetAllItems();
var groupedItems = items.GroupBy(x=> new {Year = x.DateCreate.Year, Month = x.DateCreate.Month})
.Select(s=> new ItemForListViewModel(){
   Year = s.Key.Year,
   Month = s.Key.Month,
   AvgQnt = s.Where(x=>x.Price > 10).Average(x=>x.Qnt)
}).ToList();

上面的代码给出了错误序列不包含元素,而不是我改变

 var groupedItems = items.GroupBy(x=> new {Year = x.DateCreate.Year, Month = x.DateCreate.Month})
    .Select(s=> new ItemForListViewModel(){
       Year = s.Key.Year,
       Month = s.Key.Month,
       AvgQntPrice10 = s.Where(x=>x.Price > 10).DefaultIfEmpty().Average(x=>x.Qnt),
AvgQntPrice100 = s.Where(x=>x.Price > 100).DefaultIfEmpty().Average(x=>x.Qnt
    }).ToList();

比我收到新错误: NullReferenceException:未将对象引用设置为对象的实例。

在数据库中,如果我运行查询,AvgQntPrice10 的值为 0,AvgQntPrice100 的示例为 15 是正确的。

问候, 丹尼尔

问题当然是在DefaultIfEmpty之后, Average调用的参数x可以为null (引用类型的 CLR 默认值)。

回到最初的问题 - 在空集合上调用MinMaxAverage时, Sequence 不包含元素异常。 它可以通过两种方式正确解决。

首先是,而不是DefaultIfEmpty().Average(selector) ,使用不那么简洁但有效的组合Select(selector).DefaultIfEmpty().Average() ,例如

AvgQntPrice10 = s.Where(x => x.Price > 10).Select(x => x.Qnt).DefaultIfEmpty().Average(),
AvgQntPrice100 = s.Where(x => x.Price > 100).Select(x => x.Qnt).DefaultIfEmpty().Average()

其次(也是我的首选)是利用MinMaxAverage方法的可为空重载这一事实不抛出Sequence 不包含空集合的元素异常,而是返回null 因此,您需要做的就是将选择器表达式类型转换为相应的可为空类型,并可选择使用?? 在聚合方法结果上为该情况分配一个特殊值(如0 )。

例如,如果Qnt的类型是int (如果不是,请使用正确的类型),则上面可以写为

AvgQntPrice10 = s.Where(x => x.Price > 10).Average(x => (int?)x.Qnt) ?? 0,
AvgQntPrice100 = s.Where(x => x.Price > 100).Average(x => (int?)x.Qnt) ?? 0

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM