为什么 OrderBy 总是返回零到顶部?

Why is OrderBy always returning zero to the top?

我有一个列出国家/地区的数据库。每个国家可能有零个或多个啤酒厂,每个啤酒厂都有零个或多个啤酒。我正在按照产自这些国家的啤酒数量的顺序对这些国家/地区进行排序。为此,我制作了这段代码:-

sorted_countries = db.Countries.OrderBy(x => x.Breweries.Sum(y => y.Beers.Count()));

数据库中的一个国家/地区没有啤酒厂,正如人们所预料的那样,这个国家/地区位居榜首。但是如果我颠倒顺序:-

sorted_countries = unsorted_countries.OrderBy(x => -1*x.Breweries.Sum(y => y.Beers.Count()));

没有啤酒厂的国家仍然出现在显示的顶部。

为什么会这样?

在我看来,如果将 .Sum 方法应用于空集合,结果应该始终为零,并且它会正常排序。但它似乎总是先出现,即使选择了相反的顺序。

(我可以很容易地解决这个问题,像这样:-

sorted_countries = db.Countries.OrderBy(x => x.Breweries.Count() > 0 ? 0 : 1)
                               .ThenBy(x => -1*x.Breweries.Sum(y => y.Beers.Count()));

但我想知道发生了什么,为什么这是必要的。)

编辑

按照 Andy G 的建议,我尝试了这个:-

sorted_countries = db.Countries.OrderByDescending(x => x.Breweries.Sum(y => y.Beers.Count()));

然后没有啤酒厂的国家出现在列表的底部(这是比我更好的解决问题的方法)。

编辑

根据 Jon Skeet 的建议,为 "times -1" 方法生成的 SQL 是...

SELECT [t0].[CountryID], [t0].[Name], [t0].[Code]
FROM [dbo].[Country] AS [t0]
ORDER BY (
    SELECT SUM([t3].[value])
    FROM (
        SELECT @p0 * ((
            SELECT COUNT(*)
            FROM [dbo].[Beer] AS [t2]
            WHERE [t2].[BreweryID] = [t1].[BreweryID]
            )) AS [value], [t1].[CountryID]
        FROM [dbo].[Brewery] AS [t1]
        ) AS [t3]
    WHERE [t3].[CountryID] = [t0].[CountryID]
    ), [t0].[Name]

而 OrderByDescending 产生:-

SELECT [t0].[CountryID], [t0].[Name], [t0].[Code]
FROM [dbo].[Country] AS [t0]
ORDER BY (
    SELECT SUM([t3].[value])
    FROM (
        SELECT (
            SELECT COUNT(*)
            FROM [dbo].[Beer] AS [t2]
            WHERE [t2].[BreweryID] = [t1].[BreweryID]
            ) AS [value], [t1].[CountryID]
        FROM [dbo].[Brewery] AS [t1]
        ) AS [t3]
    WHERE [t3].[CountryID] = [t0].[CountryID]
    ) DESC, [t0].[Name]

如果一个国家/地区没有啤酒厂,那么您将按 null 值排序。这些使用 OrderBy.

按升序排列在第一位

乘以 -1 不会改变 null 的位置,OrderByDescending 会。