我有一个列出国家/地区的数据库。每个国家可能有零个或多个啤酒厂,每个啤酒厂零个或多个啤酒。我将这些国家分类为有多少啤酒来自它们的顺序。为此,我生成了这段代码: -
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]
答案 0 :(得分:5)
如果某个国家/地区没有啤酒厂,那么您将按null
值进行排序。这些是使用OrderBy
按升序排列的第一个。
乘以-1不会改变null
的位置,OrderByDescending
会这样做。