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});
这有两个问题:
- 它不起作用。 EF抛出
System.NotSupportedException
; 显然,对于使用行号的.Select()
的重载,没有SQL转换; 你必须使用.ToList()
将所有内容都拉入内存,以便能够调用此方法; 和 - 即使你在本地内存中运行该方法,它也不像
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 });