如何使用 Linq 获取 IGrouping 索引到实体? (不支持异常)

How to get IGrouping index with Linq to entities ? (NotSupportedException)

我首先使用 EF 代码,然后尝试创建一个查询,该查询将根据特定列获取玩家的排名,此处为 Seniority
这是一个可能是 Players table 的例子(Rank 不是它的一部分,我需要从 Seniority 推导出它):

Username | Seniority (=> Rank)  
player1  | 25        (=> 1st)  
player2  | 20        (=> 2nd)  
player3  | 20        (=> 2nd)  
player4  | 18        (=> 3rd)  
player5  | 16        (=> 4th)  
player6  | 16        (=> 4th)  
player7  | 15        (=> 5th)  
player8  | 11        (=> 6th)  
player9  | 10        (=> 7th)  
player10 | 8         (=> 8th)  
player11 | 7         (=> 9th)  
player12 | 5         (=> 10th)  
player13 | 2         (=> 11th)  
player14 | 1         (=> 12th)  
player15 | 0         (=> 13th) 

我需要向 return 所有排名 <= 10 的玩家发出以下请求(即从玩家 1 到玩家 12),然后对其进行分页;例如第一页每页最多 10 个元素(即从 player1 到 player10)。

entities.Players
.GroupBy(p => p.Seniority)
.Where((group, groupIndex) => groupIndex <= 10)
.SelectMany((group, groupIndex) =>
    group.Select(grp =>
        new PlayerRanking()
        {
            Player = grp,
            Rank = groupIndex + 1,
            Score = grp.Seniority
        }
    )
    .OrderByDescending(r => r.Score)
    .ThenBy(r => r.Player.UserName)
)
.ToPagedList(pageNb, 10);

LINQ to Entities does not recognize the method 'System.Linq.IQueryable1[Models.BO.Ranking.PlayerRanking] SelectMany[IGrouping2,PlayerRanking](System.Linq.IQueryable1[System.Linq.IGrouping2[System.Int32,Models.BO.Players.Player]], System.Linq.Expressions.Expression1[System.Func3[System.Linq.IGrouping2[System.Int32,Models.BO.Players.Player],System.Int32,System.Collections.Generic.IEnumerable1[Models.BO.Ranking.PlayerRanking]]])', and this method cannot be translated into a store expression.

我在其他一些帖子上看到 EF 抱怨 WhereSelectMany 有两个参数,但我可以不用吗?
我不想使用 ToList()AsEnumerable() 因为如果我这样做,我想请求将枚举所有 Players 条目(这可能真的很大......)虽然我只需要其中 10 个。我真的很关心这个特定查询的性能。

有办法吗?

非常感谢。

@octavioccl

我刚刚添加了 Skip 分页部分:

var result = entities.Players.GroupBy(p => p.Seniority)
                       .OrderBy(e=>e.Key)
                       .Skip((pageNb - 1) * 10)
                       .Take(10)
                       .AsEnumerable()
                       .SelectMany((g,i)=>g.OrderBy(e=>e.UserName)
                                            .Select(e=>new PlayerRanking()
                                                       {
                                                          Player = e,
                                                          Rank = i + 1,
                                                          Score = e.Seniority
                                                       });

对于 pageNb = 1,结果似乎是正确的,我的 player1 到 player10 的排名正确:)
但是对于 pageNb = 2 排名再次从 1 重新开始(即 player11 被标记为第 1 而不是第 9)。

Linq to Entities 不支持 index 的方法重载。此外,由于 GroupBy 返回序列的任何使用(而不是 SQL GROUP BY 中的简单键 + 聚合)导致生成的 [=20= 中的 2 table 访问路径],您可以简单地手动执行此操作并使用 Count 方法来确定排名(这应该是大于当前值的不同 Seniority 值的计数)。

所以您的查询的等效工作可能是这样的:

var result = entities.Players
    .Select(p => new PlayerRanking
    {
        Player = p,
        Rank = entities.Players.Where(p1 => p1.Seniority > p.Seniority)
               .Select(p1 => p1.Seniority).Distinct().Count() + 1,
        Score = p.Seniority
    })
    .Where(r => r.Rank <= 10)
    .OrderBy(r => r.Rank)
    .ThenBy(r => r.Player.UserName)
    .ToPagedList(pageNb, 10);