任何人都知道如何设置平均值的默认值?我有这样一条线......
dbPlugins = (from p in dbPlugins
select new { Plugin = p, AvgScore = p.DbVersions.Average(x => x.DbRatings.Average(y => y.Score)) })
.OrderByDescending(x => x.AvgScore)
.Select(x => x.Plugin).ToList();
因为我没有收视率而引发错误。如果我没有,我希望平均值默认为0.我认为这应该是一个扩展方法,我可以指定默认值应该是什么。
答案 0 :(得分:42)
我不确定您的DbVersions
和DbRatings
是什么以及哪些收藏品完全没有项目,但这是个主意:
var emptyCollection = new List<int>();
var average = emptyCollection.DefaultIfEmpty(0).Average();
更新(重复以下评论中提到的内容以提高知名度)
如果您发现自己需要在类类型集合上使用DefaultIfEmpty
,请记住您可以在聚合之前将LINQ查询更改为项目。例如:
class Item
{
public int Value { get; set; }
}
var list = new List<Item>();
var avg = list.Average(item => item.Value);
如果您不希望/不能构建Item
且Value
等于0的默认int
,则可以首先投影到var avg = list.Select(item => item.Value).DefaultIfEmpty(0).Average();
的集合,然后 提供默认值:
{{1}}
答案 1 :(得分:0)
我认为没有办法选择默认值,但这个查询怎么样
dbPlugins = (from p in dbPlugins
select new {
Plugin = p, AvgScore =
p.DbVersions.Any(x => x.DbRatings) ?
p.DbVersions.Average(x => x.DbRatings.Average(y => y.Score)) : 0 })
.OrderByDescending(x => x.AvgScore)
.Select(x => x.Plugin).ToList();
基本上与你的相同,但我们首先询问在平均它们之前是否有任何评级。如果没有,我们返回0。
答案 2 :(得分:0)
我的建议是创建一个可重用的解决方案,而不是仅针对此问题的解决方案。
设置扩展方法AverageOrDefault,类似于FirstOrDefault。参见extension methods demystified
public static class MyEnumerableExtensions
{
public static double AverageOrDefault(this IEnumerable<int> source)
{
// TODO: decide what to do if source equals null: exception or return default?
if (source.Any())
return source.Average();
else
return default(int);
}
}
Enumerable.Average有9个重载,因此您需要为double,int?,decimal等创建一个AverageOrDefault。它们看起来都相似。
用法:
// Get the average order total or default per customer
var averageOrderTotalPerCustomer = myDbContext.Customers
.GroupJoin(myDbContext.Orders,
customer => customer.Id,
order => order.CustomerId,
(customer, ordersOfThisCustomer) => new
{
Id = customer.Id,
Name = customer.Name,
AverageOrder = ordersOfThisCustomer.AverageOrDefault(),
});
答案 3 :(得分:-2)
我尝试了其中一些答案但最终由于某种原因而获得了更多例外。这最终为我工作。我确信表现很糟糕但我稍后会修改。
var q1 = from v in db.DbVersions select new { VersionId = v.Id, AvgScore = v.DbRatings.Average(x => x.Score) as Nullable<double> };
var q2 = from p in dbPlugins select new { Plugin = p, AvgScore = q1.Where(x => p.DbVersions.Select(y => y.Id).Contains(x.VersionId)).Average(x => x.AvgScore) as Nullable<double> };
dbPlugins = q2.OrderByDescending(x => x.AvgScore).Select(x => x.Plugin).ToList();