实体框架中是否有一个函数可以转换为 SQL 中的 RANK() 函数

本文关键字:函数 SQL 中的 RANK 转换 框架 是否 有一个 实体 | 更新日期: 2023-09-27 18:34:19

假设我想按国家/地区对我的客户数据库进行排名。 在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;显然,对于使用行号的重载.Select(),没有 SQL 转换;您必须使用.ToList()将所有内容拉入内存才能调用此方法;和
  2. 即使您在本地内存中运行该方法,它也不会像 RANK() 函数在 SQL 中那样处理相等的排名,即它们应该具有相等的排名,然后以下项跳到原始顺序。

那么我应该怎么做呢?

实体框架中是否有一个函数可以转换为 SQL 中的 RANK() 函数

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