我们有一个包含数千个条目的数据库。我们希望获得排名第34位的排名。对于特定项目的名称。
由于存在大量数据,我们希望避免带来查询所有数据以确定行索引(例如,使用ToList()
和IndexOf()
)。
我尝试使用
List<Ranking> ranking = _context.Testes
.OrderByDescending(t => t.Val)
.Select((d, i) => new Ranking() {
Name = d.Name,
Ranking= i
}).First(d=>d.Name = "Test");
但是我收到了这个错误:
&#39; value(Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1 [WebApplication4.Models.Teste])。OrderByDescending(t =&gt; t.Val).Select((d,i)=&gt; new Ranking(){Name = d.Name,Ranking = i})&#39;:方法的重载&#39; System.Linq.Queryable.Select&#39;目前不支持。
这有可能吗?
答案 0 :(得分:3)
您无法将此Select()重载转换为SQL。 ORM不用于报告,这是100%的报告查询。
SQL Server提供ranking functions,例如ROW_NUMBER,RANK和DENSE_RANK。您可以创建一个计算排名并将排名映射到它的视图,例如:
CREATE VIEW Rankings
AS
SELECT
Name,
DENSE_RANK() OVER(ORDER BY Val) Ranking
From Tests
如果两个记录绑定并继续下一个排名,则 DENSE_RANK()
将返回相同的排名。 ROW_NUMBER只会使用递增数字。如果你使用ROW_NUMBER
,你应该使用额外的排序标准来避免为关系生成随机排名。
EF可能会按照惯例将排名类映射到排名视图。如果没有,则使用Table属性映射它,如果使用Code-First配置,则映射ToTable
:
[Table("Rankings")
public class Ranking
{
public string Name{get;set;}
public int Ranking {get;set;}
}
检索特定排名只需要Where()
子句:
var someRanking=context.Rankings.Where(r=>r.Name=someName);
答案 1 :(得分:1)
在LINQ中(注意你必须处理关系以获得明确定义的排名)
DEPT = (
('Production', 'Production'),
('Purchasing', 'Purchasing'),
('Support', 'Support')
)
转换为
var q = from t in db.Testes
where t.Name == "whatever"
select new
{
Testes =t,
Rank =1+db.Testes.Where(ot => ot.Val < t.Val || (ot.Val == t.Val && ot.Id < t.Id) ).Count()
};