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