关于Linq to Sql的分页

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于Linq to Sql的分页相关的知识,希望对你有一定的参考价值。

有一个名为Customer的Linq to Sql实体类,下面是分页查询:
public IQueryable<Customer> GetCustomer(out int count, int pageSize, int pageIndex)

count = db.Count();

//动态生成查询表达式
var query = db.Customer.OrderBy(customer=> customer.CustomerID)
.Skip(pageSize * (pageIndex - 1)).Take(pageSize);
//返回查询的表达式目录树
return query;

其中db是DataContext的实例,在类成员中定义。
假如每页数据大小pageSize为10,,当pageIndex为1的时候,我想查询第1条至第10条数据,但是linq语句中的Skip(0)却查询不到表中的第一条数据,是从第2条数据开始到第11条数据的,应该怎么解决?我用的是.NET4.0,我在网上看到说这个问题是.NET3.5中的bug,.NET4.0中已经解决了,但我的还是不行,求解。
有个地方写错了,count=db.Customer.Count();

我没遇到这情况啊,实在不行,你就这样
public IQueryable<Customer> GetCustomer(out int count, int pageSize, int pageIndex)

count = db.Customer.Count();
int startIndex=pageSize * (pageIndex - 1);
//动态生成查询表达式
if(startIndex<=0)

return db.Customer.OrderBy(customer=> customer.CustomerID)
.Take(pageSize);
else

return db.Customer.OrderBy(customer=> customer.CustomerID)
.Skip().Take(pageSize);
//返回查询的表达式目录树



ok不追问

看来问题没那么简单,刚才又测试了一下,即使不是查询第一页,比如查询第3页,linq里就是Skip(20),查询的数据竟然是从22到31,而不是21到30!

呃。。。发现问题了,我以前的写法是没问题的,是我数据库中的数据记录有问题,我没注意,看来.NET4.0中果然是修复了这个bug。还是谢谢你的回答!

参考技术A class table

public string id


private void Window_Loaded(object sender, RoutedEventArgs e)

List<table> ls = new List<table>();
for (int i = 0; i < 10; i++)
ls.Add(new table );

int pageSize = 3;
int currentPage = 2;

var linq = (from t in ls.ToArray()
where
(from t2 in ls.ToArray() select t2.id).Take(pageSize * (currentPage - 1)).ToArray().Contains(t.id) == false
select t).Take(pageSize);

foreach (var l in linq)
this.Title += l.id + ",";

追问

你这是在表示层才进行分页,为了系统性能考虑我需要在数据层就进行分页,避免把大量数据一次性读到内存中再分页。所以我在数据访问层返回的是IQueryable类型,生成的是表达式目录树,而不是读取所有数据记录。只有当调用结果的时候才进行查询操作,要充分利用linq的延迟查询功能。所以你的写法我是没法用的,不好意思。

使用 LINQ to SQL 分页搜索结果

【中文标题】使用 LINQ to SQL 分页搜索结果【英文标题】:Paginated search results with 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);

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

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

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

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

【问题讨论】:

【参考方案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 方法的存在。但是,如果我真的想分页,我必须知道不分页的结果总数是多少。那么,获得总数的最佳方法是什么?

以上是关于关于Linq to Sql的分页的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 多页分页

页面设置中“分页符”和“下一页”的区别是啥?

dede织梦文章页分页导航副标题如何删除标题后面带的#号

使用 LINQ to SQL 分页搜索结果

django的分页--不全也未实现

关于Java的分页算法,急!