【问题标题】:Paginated search results with LINQ to SQL使用 LINQ to SQL 分页搜索结果
【发布时间】:2010-10-22 01:52:50
【问题描述】:

使用 LINQ to SQL 获得分页结果的最佳模式是什么?

我有以下场景:

假设我想通过 description 搜索 items 表。我可以轻松做到:

public IQueryable<Item> FindItemsByDescription(string description)
{
   return from item in _dc.Items
          where item.Description.Contains(description);
}

现在,对该结果集进行分页的最佳方法是什么?

  1. 我是否应该在执行此操作之前执行 count 查询以找出结果集大小,然后根据我的需要限制此查询?我觉得这是要走的路。
  2. 我是否应该执行完整的查询,从数组大小中获取计数并只返回该数组的分页子集?如果结果集足够大,我觉得这将浪费大量时间......或者 LINQ to SQL 在这里做了什么魔术?

是否有用于执行此操作的 LINQ to SQL 通用模式?

编辑:我必须澄清一件小事。我知道 Take 和 Skip 方法。但是,在使用 TakeSkip 之前,我应该如何获得查询将检索到的结果的total count

【问题讨论】:

    标签: c# linq linq-to-sql pagination


    【解决方案1】:

    分页模式非常简单。它涉及到 Skip() 和 Take() 扩展方法的使用,如下所示:

    public IQueryable<Item> FindItemsByDescription(string description, int pageIndex, int pageSize)
    {
       return from item in _dc.Items
              where item.Description.
              Contains(description).
              Skip((pageIndex - 1) * pageSize).
              Take(pageSize);
    }
    

    更新:要获得总数,只需使用 Count() 方法:

    int totalCount = from item in _dc.Items
                     where item.Description.
                     Contains(description).Count();
    
    int numberOfPages = (int)(totalCount/pageSize);
    

    根据您要如何显示记录,您可以使用 numberOfPages 显示一个导航栏,其中包含“第 X 页,共 Y”...第 1 页,共 10 页等。

    【讨论】:

    • Pablo - 我更新了我的帖子以包含有关分页的更多信息。 (Salu2)
    • 非常感谢巴西利奥。这是性能明智的最佳方法吗?你知道用这种方法会对 SQL Server 执行多少查询吗?
    • Pablo - 示例中的代码将执行 2 个单独的 SQL 查询。但是,情况并非必须如此。您可以从查询中获取结果并使用 ToList() 将其放入列表中,然后从中获取 Count()。这样您最终只需要调用一次数据库。
    • "(int)(totalCount/pageSize)" 是错误的。假设您有 5 个项目,页面大小为 4?页数将是 1 而不是 2。您还需要测试是否 totalCount%pageSize==0 并添加另一个单元。
    • 对于numberOfPages,我使用了Math.Ceiling 方法,例如int numberOfPages = (int) Math.Ceiling((double) totalCount/pageSize);
    【解决方案2】:

    您可以使用 Take 扩展方法:

    public IQueryable<Item> FindItemsByDescription(string description, int resultAmount)
    {
       return from item in _dc.Items
              where item.Description.Contains(description).Take(resultAmount);
    }
    

    您可以更进一步,为后续的“页面”使用 Skip:

    public IQueryable<Item> FindItemsByDescription(string description, int resultAmount, int page)
    {
       return from item in _dc.Items
              where item.Description.Contains(description).Skip(resultAmount * page).Take(resultAmount);
    }
    

    【讨论】:

    • 非常感谢您的快速回答。我知道 Take 和 Skip 方法的存在。但是,如果我真的想分页,我必须知道不分页的结果总数是多少。那么,获得总数的最佳方法是什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-07
    相关资源
    最近更新 更多