[英]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 默认值)。
回到最初的问题 - 在空集合上调用Min
、 Max
或Average
时, 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()
其次(也是我的首选)是利用Min
、 Max
和Average
方法的可为空重载这一事实不抛出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.