Reputation: 797
I'm wondering if it is possible to use a lambda expression to order a list of items based on the average value of a nested list of items.
In project terms, I have a list of products that each can have many reviews. I want to order the list of the products based on the average rating from each product's list of reviews.
I have this:
products = category.Products.OrderBy(i => i.Reviews.Average(x => x.Rating));
This builds without a problem but when I run it, it returns an error that says
Sequence contains no elements
Is it possible to do this with a lambda expression?
Upvotes: 0
Views: 1097
Reputation: 460148
Enumerable.Average
throws the InvalidOperationException
because the sequence contains no elements since a product has no Reviews
.
You could use Enumerable.DefaultIfEmpty(customValue)
:
products = category.Products
.OrderBy(i => i.Reviews.Select(r => r.Rating).DefaultIfEmpty(0).Average());
Maybe you want to exclude these products from the result:
products = category.Products
.Where(p => p.Reviews.Any())
.OrderBy(p => p.Reviews.Average(r => r.Rating));
Upvotes: 6
Reputation: 39013
One of your products probably has no reviews. You should decide what rating to give it, let's say 99 because you want it to appear at the end, so:
category.Products.OrderBy(p=>p.Reviews.Count > 0 ?
p.Reviews.Average(r=>r.Rating) : 99);
Upvotes: 2