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;