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

时间:2018-01-22 10:59:39

标签: c# linq-to-sql sum

我有一个列出国家/地区的数据库。每个国家可能有零个或多个啤酒厂,每个啤酒厂零个或多个啤酒。我将这些国家分类为有多少啤酒来自它们的顺序。为此,我生成了这段代码: -

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所建议的那样,为"时间-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]

1 个答案:

答案 0 :(得分:5)

如果某个国家/地区没有啤酒厂,那么您将按null值进行排序。这些是使用OrderBy按升序排列的第一个。

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