如何使用实体框架在SQL数据库中获取行索引而不查询所有数据?

时间:2017-06-13 13:28:19

标签: c# sql-server entity-framework linq

我们有一个包含数千个条目的数据库。我们希望获得排名第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;目前不支持。

这有可能吗?

2 个答案:

答案 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()
                      };