我首先使用EF
代码,并且我尝试创建一个基于特定列获得玩家排名的查询,Seniority
。
以下是Players
表格的示例(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)
我需要以下请求才能返回排名为< = 10(即从player1到player12)的所有玩家,然后将其分页;例如,每页有10个最大元素的第一页(即从播放器1到播放器10)。
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无法识别方法&#39; System.Linq.IQueryable
1[Models.BO.Ranking.PlayerRanking] SelectMany[IGrouping
2,PlayerRanking](System.Linq.IQueryable1[System.Linq.IGrouping
2 [System.Int32,Models.BO。 Players.Player]],System.Linq.Expressions.Expression1[System.Func
3 [System.Linq.IGrouping2[System.Int32,Models.BO.Players.Player],System.Int32,System.Collections.Generic.IEnumerable
1 [Models.BO.Ranking.PlayerRanking]]])&#39;,这个方法无法转换为商店表达式。
我在其他一些帖子中看到EF
抱怨Where
和SelectMany
有两个论点,但我可以不这样做吗。
我不想使用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
,结果似乎是正确的,我有玩家1到玩家10的正确等级:)
但是对于pageNb = 2
,Rank再次从1重新开始(即,player11被标记为1st而不是9)。
答案 0 :(得分:2)
Linq to Entities不支持index
的方法重载。此外,由于GroupBy
返回序列的任何使用(而不仅仅是SQL GROUP BY
中的键+聚合)导致生成的SQL中有2个表访问路径,您可以手动执行此操作并使用{{ 1}}确定排名的方法(应该是大于当前的不同Count
值的计数)。
因此,查询的工作等价物可能是这样的:
Seniority