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

时间:2014-12-14 13:32:39

标签: c# sql-server-2012 entity-framework-5

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

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

现在我想在实体框架中写这个:

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;显然,使用行号的overload of .Select()没有SQL翻译;你必须使用.ToList()将所有内容都拉入内存,以便能够调用此方法;和
  2. 即使你在本地内存中运行该方法,它也不像RANK()函数在SQL中那样处理相同的排名,即它们应该具有相同的排名,然后下面的项目跳到原始的顺序。
  3. 那我该怎么做呢?

1 个答案:

答案 0 :(得分:5)

AFAIK Rank()在LINQ中没有内置函数。 This answer使用您的方法,但似乎对他们有效。以下是如何使用它:

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
        });