如何使用Entity Framework在动态构建的查询中按实体键获取行索引

Căl*_*rie 6 .net c# sql-server linq-to-entities entity-framework

在网格中,我需要通过其ID来寻呼记录.这就是为什么我需要在用户过滤和用户排序的集合中找到它的索引.

我正在使用LINQ to Entities.查询是基于用户输入动态构建的.

该表包含太多(超过10 ^ 5)条记录,因为以下Stack Overflow建议是有益的:

Recs = Recs.Where( /* Filters */ );
Recs = Recs.OrderBy( /* Sort criteria */ );
Recs.AsEnumerable()
        .Select((x,index) => new {RowNumber = index, Record = x})
        .Where(x=>x.Record.ID = 35);
Run Code Online (Sandbox Code Playgroud)

由于LINQ to Entities不支持Select((entity, index) => ...),因此需要从SQL服务器下载250,000条记录,因此我可以决定显示第25,000页.

目前,我最有希望的想法是将每个排序标准转换为过滤器.因此,找到按升序高度排序的人的索引将计入较短的人(排序标准'高度上升'=>过滤器'高度小于'+计数).

我该怎么做呢?这个问题已经解决了吗?有没有.NET的图书馆,甚至我的一半?

Adu*_*cci 3

这是一个递归函数,您可以调用它来计算行号。如果您的数据库记录经常更改,它可能不起作用,因为这会多次调用数据库,每次都会将搜索范围缩小一半。

public static int FindRowNumber<T>(IQueryable<T> query, Expression<Func<T, bool>> search, int skip, int take)
{
  if(take < 1) return -1;
  if(take == 1) return query.Skip(skip).Take(take).Any(search) ? skip : -1;      


  int bottomSkip = skip;
  int bottomTake = take / 2;
  int topSkip = bottomTake + bottomSkip;
  int topTake = take - bottomTake;

  if(query.Skip(bottomSkip).Take(bottomTake).Any(search))
  {        
    return FindRowNumber(query, search, bottomSkip, bottomTake);
  }
  if(query.Skip(topSkip).Take(topTake).Any(search))
  {
    return FindRowNumber(query, search, topSkip, topTake);
  }

  return -1;
}
Run Code Online (Sandbox Code Playgroud)

你这样称呼它:

var query = ... //your query with ordering and filtering
int rownumber = FindRowNumber(query, x => x.Record.ID == 35, 0, query.Count());
Run Code Online (Sandbox Code Playgroud)