Entity Framework中是否有一个函数转换为SQL中的RANK()函数?

假设我想按国家/地区对客户数据库进行排名。 在SQL中我会写:

select CountryID, CustomerCount = count(*), [Rank] = RANK() over (order by count(*) desc) from Customer 

现在我想在Entity Framework中写这个:

 var ranks = db.Customers .GroupBy(c => c.CountryID) .OrderByDescending(g => g.Count()) .Select((g, index) => new {CountryID = g.Key, CustomerCount = g.Count, Rank = index+1}); 

这有两个问题:

  1. 它不起作用。 EF抛出System.NotSupportedException ; 显然,对于使用行号的.Select()的重载,没有SQL转换; 你必须使用.ToList()将所有内容都拉入内存,以便能够调用此方法; 和
  2. 即使你在本地内存中运行该方法,它也不像RANK()函数在SQL中那样处理相同的排名,即它们应该具有相同的排名,然后下面的项目跳到原始顺序。

那我该怎么做呢?

AFAIK Rank()在LINQ中没有内置函数。 这个答案使用了你的方法,但它似乎适用于他们。 以下是您可以使用它的方法:

 var customersByCountry = db.Customers .GroupBy(c => c.CountryID); .Select(g => new { CountryID = g.Key, Count = g.Count() }); var ranks = customersByCountry .Select(c => new { c.CountryID, c.Count, Rank = customersByCountry.Count(c2 => c2.Count > c.Count) + 1 });