C.J*_*.J. 56 entity-framework entity-framework-4 c#-4.0 entity-framework-4.1
目前,当我需要运行将使用w/paging的查询时,我会这样做:
//Setup query (Typically much more complex)
var q = ctx.People.Where(p=>p.Name.StartsWith("A"));
//Get total result count prior to sorting
int total = q.Count();       
//Apply sort to query
q = q.OrderBy(p => p.Name);  
q.Select(p => new PersonResult
{
   Name = p.Name
}.Skip(skipRows).Take(pageSize).ToArray();
Run Code Online (Sandbox Code Playgroud)
这有效,但我想知道是否有可能在使用linq时提高效率更高效?我想不出一种方法可以使用存储过程将数据检索的计数与数据检索结合到数据库中.
Jef*_*ata 77
以下查询将在一次数据库中获取计数和页面结果,但如果在LINQPad中检查SQL,则会发现它不是很漂亮.我只能想象一下更复杂的查询会是什么样子.
var query = ctx.People.Where (p => p.Name.StartsWith("A"));
var page = query.OrderBy (p => p.Name)
                .Select (p => new PersonResult { Name = p.Name } )          
                .Skip(skipRows).Take(pageSize)
                .GroupBy (p => new { Total = query.Count() })
                .First();
int total = page.Key.Total;
var people = page.Select(p => p);
Run Code Online (Sandbox Code Playgroud)
对于像这样的简单查询,你可以使用任何一种方法(2次访问数据库,或者GroupBy在1次旅行中使用它)并没有注意到很多不同.对于任何复杂的事情,我认为存储过程将是最好的解决方案.
Jeff Ogata的答案可以稍微优化一下.
var results = query.OrderBy(p => p.Name)
                   .Select(p => new
                   {
                       Person = new PersonResult { Name = p.Name },
                       TotalCount = query.Count()
                   })          
                   .Skip(skipRows).Take(pageSize)
                   .ToArray(); // query is executed once, here
var totalCount = results.First().TotalCount;
var people = results.Select(r => r.Person).ToArray();
Run Code Online (Sandbox Code Playgroud)
这几乎完全相同,除了它不会打扰带有不必要的GROUP BY的数据库.当您不确定您的查询将包含至少一个结果,并且不希望它抛出异常时,您可以获得totalCount以下(虽然不太清晰)的方式:
var totalCount = results.FirstOrDefault()?.TotalCount ?? 0;
Run Code Online (Sandbox Code Playgroud)
        使用EF Core> = 1.1.x && <3.0.0的人员的重要说明:
当时我正在寻找解决方案,此页面在Google术语“ EF核心分页总数”中排名第1。
检查完SQL事件探查器后,我发现EF SELECT COUNT(*)为返回的每一行生成一个。我已经厌倦了此页面上提供的所有解决方案。
这是使用EF Core 2.1.4和SQL Server 2014进行了测试。最后,我不得不像两个单独的查询一样执行它们。至少对我来说,这不是世界末日。
var query = _db.Foo.AsQueryable(); // Add Where Filters Here.
var resultsTask = query.OrderBy(p => p.ID).Skip(request.Offset).Take(request.Limit).ToArrayAsync();
var countTask = query.CountAsync();
await Task.WhenAll(resultsTask, countTask);
return new Result()
{
    TotalCount = await countTask,
    Data = await resultsTask,
    Limit = request.Limit,
    Offset = request.Offset             
};
Run Code Online (Sandbox Code Playgroud)
看起来EF核心团队已经意识到了这一点:
https://github.com/aspnet/EntityFrameworkCore/issues/13739 https://github.com/aspnet/EntityFrameworkCore/issues/11186
我建议对第一页进行两次查询,一次查询总数,一次查询第一页或结果。
缓存总计数,以便在您超出第一页时使用。
|   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           27679 次  |  
        
|   最近记录:  |