简体   繁体   English

LINQ Take()一遍又一遍地返回相同的结果

[英]LINQ Take() returns the same results over and over

I want to page over some records but the Take() extension from LINQ isn't returning the result which I expected. 我想翻页一些记录,但是LINQTake()扩展没有返回我期望的结果。

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

When I run this method again, I get the same result. 当我再次运行此方法时,我得到相同的结果。 How exactly does Take() work? Take()到底如何工作?

The Take method returns the first N records (N being the parameter) or all of the records if the total is less than N. To implement paging use it in conjunction with Skip , specifying how many records to skip before taking the next page of results. Take方法返回前N条记录(N为参数)或所有记录(如果总数小于N)。要实现分页,请与Skip结合使用,指定在获取下一页结果之前要跳过多少条记录。 You may also want to supply some total ordering to ensure that the query returns results in the same order each time. 您可能还希望提供一些总体排序,以确保查询每次都以相同的顺序返回结果。

Note: I've assumed zero-based paging. 注意:我假设基于零的分页。

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);
}

.Take returns the specified number of results on a query, and if it is the same query it will often return the same results. .Take在查询中返回指定数量的结果,如果是相同的查询,则通常会返回相同的结果。 To resolve this, you might use a combination of .Skip and .Take , changing the number you are Skip ping and Take ing each time. 为了解决这个问题,你可以使用的组合.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;
}

Keep in mind that you will be able to call this continuously, even after there are no more records. 请记住,即使没有更多记录,您也可以连续调用此函数。

Alternatively, you could cache the query (if you aren't reinstantiating the class on each use): 或者,您可以缓存查询(如果您不打算在每次使用时重新实例化该类):

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);
}

Nevertheless, both of these snippets may have other issues -- see tvanfosson's comments and answer. 但是,这两个片段可能还有其他问题-请参阅tvanfosson的评论和答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM