C# 试图除以零Linq
我试图根据列的总数和有多少列来计算平均值 每部电影都可以有一部电影,我试着把电影数量加起来,然后除以收视率,得到一部电影的平均收视率C# 试图除以零Linq,c#,linq,C#,Linq,我试图根据列的总数和有多少列来计算平均值 每部电影都可以有一部电影,我试着把电影数量加起来,然后除以收视率,得到一部电影的平均收视率 (reviews.Where(w => w.MovieID == m.MovieID).Sum(o => o.MovieRating)) / reviews.Where(z => z.MovieID == m.MovieID).Count(); 但问题是如果计数为0。对此我能做些什么?使用LINQs内置的平均值函数怎么样 reviews
(reviews.Where(w => w.MovieID == m.MovieID).Sum(o => o.MovieRating)) / reviews.Where(z => z.MovieID == m.MovieID).Count();
但问题是如果计数为0。对此我能做些什么?使用LINQs内置的
平均值函数怎么样
reviews
.Where(z => z.MovieID == m.MovieID)
.Select(z => z.MovieRating)
.DefaultIfEmpty(0)
.Average()
要使查询在服务器上完全运行(我想,这取决于您的数据库服务器):
你可以用
var ratingList = reviews
.Where(z => z.MovieID == m.MovieID)
.Select(z => z.MovieRating)
.ToList();
if(ratingList.Count > 0)
{
double result = ratingList.Sum() / ratingList.Count;
}
我想做一个查询(因为我们可能正在处理一个数据库,每个查询都有一个成本“仅仅因为它是一个查询”),并执行SQL端的所有计算,这样我就可以返回一行(因为如果有1000篇评论,我真的不需要下载所有的评论……我想要的是他们的MovieRating
和他们的计数之和)
如果没有对电影ID
的评论,则结果将是-1.0
。请注意cast的使用,否则我们可能会有整数除法(如果电影
是整数)
请注意,如果找不到行,则不会有任何除法(因为不会有任何组
)
SQL数据库上的等效查询应为
SELECT CAST(SUM(x.MovieRating) AS FLOAT) / COUNT(*)
FROM Reviews x
WHERE x.MovieID = @MovieID
GROUP BY 1
但事实上,EF以一种更为复杂的方式对其进行了翻译:-)(在EF 6.2.0上进行了测试):
不确定是否特别强调LINQ的使用,但我更愿意将其全部放在for/foreach循环中,而不是多个LINQ。否则下面的方法行吗
var matchingReviews = reviews.Where(w => w.MovieID == m.MovieID);
int matchingReviewCount = matchingReviews.Count();
if (matchingReviewCount > 0)
{
matchingReviews.Sum(o => o.MovieRating) / matchingReviewCount;
}
else
{
//return default value?
}
如果条件如下,只需使用内联:
var avr = (from a1 in reviews
where a1.MovieID == m.MovieID
group a1 by a1.MovieID into g
select new
{
avr = g.count() == 0 ? 0 : g.sum(r => r.MovieRating) / g.count()
}).FirstOrDefault().avr;
如果没有匹配的ID,那么期望的结果是什么?如果没有评论,只需将其设置为null。我看到多枚举alsoLinq已经有了一种方法。您如何区分没有评论的电影和有大量0评论的电影?或者允许的最低审阅值是否大于零?如果审阅
是EF上的一个表,是否可以在一次往返中完全在SQL端执行此操作(无需下载lsit审阅)。其余部分在内存中完成。您可以在列表
@Tim之前添加一个。选择(m=>m.MovieRating)
。如果评论是一大行,您将下载整行。。。如果有1.000.000行,则您正在下载1000000行。。。我想说的是,我可以从EF中MovieID=@MovieID
的评论中选择COUNT(*)、SUM(MovieRating)吗?(这只是出于好奇,可能不在OP的问题范围内)这也是我想到的一个解决方案(尽管你比我先想到了)但感觉我们应该可以做些什么来优化它。@Camiloteriento此答案的解释量与两个投票结果相同。警告:Microsoft.EntityFrameworkCore.Query[20500]LINQ表达式“DefaultIfEmpty(\uu p\u 0)'无法翻译,将在本地计算。警告:Microsoft.EntityFrameworkCore.Query[20500]无法翻译LINQ表达式'Average()',将在本地计算。??空值
?真的吗?@bonmelding??null将一个合并
添加到生成的SQL中,经过反思,在本例中不需要它,我已将其删除
SELECT CAST(SUM(x.MovieRating) AS FLOAT) / COUNT(*)
FROM Reviews x
WHERE x.MovieID = @MovieID
GROUP BY 1
SELECT
CAST( [GroupBy1].[A1] AS float) / CAST( [GroupBy1].[A2] AS float) AS [C1]
FROM ( SELECT
[Filter1].[K1] AS [K1],
SUM([Filter1].[A1]) AS [A1],
COUNT([Filter1].[A2]) AS [A2]
FROM ( SELECT
1 AS [K1],
[Extent1].[MovieRating] AS [A1],
1 AS [A2]
FROM #Reviews AS [Extent1]
WHERE [Extent1].[MovieId] = @p__linq__0
) AS [Filter1]
GROUP BY [K1]
) AS [GroupBy1]
var matchingReviews = reviews.Where(w => w.MovieID == m.MovieID);
int matchingReviewCount = matchingReviews.Count();
if (matchingReviewCount > 0)
{
matchingReviews.Sum(o => o.MovieRating) / matchingReviewCount;
}
else
{
//return default value?
}
var avr = (from a1 in reviews
where a1.MovieID == m.MovieID
group a1 by a1.MovieID into g
select new
{
avr = g.count() == 0 ? 0 : g.sum(r => r.MovieRating) / g.count()
}).FirstOrDefault().avr;