LINQ Take()反复返回相同的结果

时间:2013-09-07 21:25:39

标签: c# linq entity-framework

我想翻页某些记录,但Take()的{​​{1}}扩展名未返回我预期的结果。

LINQ

当我再次运行此方法时,我得到相同的结果。 public IQueryable<Person> GetPersonBetweenDates(DateTime start, DateTime end) { return dbcontext.Persons.Where(x => x.RegisterDate >= start && x.RegisterDate <= end).Take(20); } 究竟是如何运作的?

2 个答案:

答案 0 :(得分:6)

Take方法返回前N个记录(N为参数)或所有记录(如果总数小于N)。要实现分页,请将其与Skip结合使用,指定如何在拍摄下一页结果之前要跳过的许多记录。您可能还希望提供一些总排序,以确保查询每次都以相同的顺序返回结果。

注意:我假设从零开始的分页。

private const int _pageSize = 20;

public IQueryable<Person> GetPersonBetweenDates(DateTime start, DateTime end, int? page)
{
     return dbcontext.Persons
                     .Where(x => x.RegisterDate >= start && x.RegisterDate <= end)
                     .OrderBy(x => x.LastName)
                     .ThenBy(x => x.FirstName)
                     .ThenBy(x => x.Id) // using unique id to force consistent total order
                     .Skip((page ?? 0) * _pageSize)
                     .Take(_pageSize);
}

答案 1 :(得分:5)

.Take在查询中返回指定数量的结果,如果它是同一个查询,它通常会返回相同的结果。要解决此问题,您可以使用.Skip.Take的组合,每次更改Skip ping和Take的数字。

private int counter = 0;
public IQueryable<Person> GetPersonBetweenDates(DateTime start, DateTime end)
{
    var results = dbcontext.Persons.Where(x => x.RegisterDate >= start && x.RegisterDate <= end).Skip(counter).Take(20);
    counter += 20;
    return results;
}

请记住,即使没有更多记录,您也可以连续拨打电话。

或者,您可以缓存查询(如果您没有在每次使用时重新实例化该类):

private IQueryable<Person> qry = dbcontext.Persons.Where(x => x.RegisterDate >= start && x.RegisterDate <= end);
public IQueryable<Person> GetPersonBetweenDates(DateTime start, DateTime end)
{
    qry = qry.Skip(20);
    return qry.Take(20);
}

尽管如此,这两个片段可能还有其他问题 - 请参阅tvanfosson的评论和回答。