65.9K
CodeProject 正在变化。 阅读更多。
Home

ASP.NET 中的数据分页

2001 年 12 月 2 日

6分钟阅读

viewsIcon

351477

downloadIcon

3485

如何在 ASP.NET 中显示多页记录

引言

首先,我想就本文谈几句。本文并非一篇完全原创的文章,而是我对几个月前发布的 ASP 文章的 ASP.NET 版本。您可以在这里找到原文:ASP 中的 ADO Recordset 分页

本文的目的是展示如何在 ADO.NET 中实现数据分页。它并非一篇通用的 ASP.NET 或 ADO.NET 教程。本文关注的是一种特定情况,即您需要更好地控制自己向用户提供的数据的自定义呈现和导航。这就是为什么您在这里看不到任何 WebForms 或 WebControls。我也没有使用新的 DataGrid 控件,尽管它带有数据分页功能。DataGrid 控件非常强大,并且具有许多有用的功能,但在数据呈现和页面导航链接方面却有些局限。此外,还有许多关于如何使用 ASP.NET 新功能的示例和文章是由其他人撰写的。

我偶尔会遇到在 Web 上显示大量记录的任务。一个很好的例子是显示搜索结果。大多数情况下,我无法预先知道需要显示多少条记录。此外,随着应用程序的使用增长,数据库的大小也会相应增长。这使得我和其他有类似应用程序需求的人别无选择,只能开发某种算法将记录显示为更小的块——分页。

大家都很熟悉搜索引擎显示搜索结果的方式。您会看到第一页结果,限制为一定数量的记录(例如 20 条),以及一些导航链接,用于转到第一页、上一页、下一页或最后一页。有些网站允许您直接转到特定页码,有些则混合使用这两种方式。

那么,如何在 ASP.NET 中实现数据分页机制?具体来说,我们如何使用 ADO.NET 实现记录分页?

让我们假设我们有一个数据库,其中有一个名为 tblItem 的表,用于存储我们的 Item(无论它们是什么?)的信息。我还设想 tblItem 中的一个字段名为 ItemName。我们的任务是创建一个页面集,让用户能够根据 ItemName 字段搜索 Item。我们决定创建两页。一页将显示搜索表单,另一页用于显示搜索结果。

请原谅我,我将跳过所有变量声明和 HTML 格式。

第一页应该很容易。它是一个标准的 HTML 表单,看起来可能像这样

...
<FORM ACTION="results.asp" METHOD="GET">
Item Name: <INPUT TYPE="text" NAME="Keyword"> <INPUT TYPE="submit" VALUE=" Find ">
</FORM>
...

第二页才是所有魔法发生的地方。这是第二页(results.aspx)应该能够做的事情
1. 接收用户输入的关键字。
2. 在数据库中搜索包含关键字的记录。
3. 显示一页结果记录。
4. 为用户提供一些导航链接,以便在需要时显示更多页结果。

1. 接收关键字

接收关键字就像这样做

Keyword = Request.QueryString("Keyword").Trim()

2. 搜索数据库并检索数据。

现在,我们已经拥有了使用 ADO.NET DataSet 获取包含我们关键字的 Item 的所有必要条件,这些 Item 的 ItemName 字段包含我们的关键字。

首先,我们创建一个将执行搜索的 SQL 语句

SQL = "SELECT * FROM tblItem WHERE ItemName LIKE '%" & Keyword.Replace("'", "''") & "%'"

请注意,我使用了 Replace 函数来双击搜索字符串中的单引号。否则,如果用户在关键字中输入单引号,您将收到错误。

让我们尝试打开数据库连接并获取数据

	Try
		odConn = New OleDbConnection(strConn)
		odAdapt = New OleDbDataAdapter(SQL, odConn)
		DS = New DataSet
		odAdapt.Fill(DS)
		
		' Get our DataTable
		DT = DS.Tables(0)

		' Get record count
		nRecCount = DT.Rows.Count

	Catch e As Exception
		Response.Write("Error: <b>" & e.Message & "</b><p>")
		nRecCount = 0
	End Try

以上代码行说明了以下内容:首先,我们使用连接字符串创建一个新的 OleDbConnection 对象。然后,我们创建一个 OleDbDataAdapter,提供 SQL 语句和连接对象的引用。在创建新的 DataSet 对象后,我们指示 DataAdapter 使用数据库中的数据填充 (fill) DataSet。然后,我们获取 DataSet 中代表我们数据的第一个表的引用,并检索该表中返回的记录数(行数)。TryCatch 显然用于尝试和捕获这些数据库操作期间的任何错误。

4. 导航链接

是的,这是第四步。我将第三步(显示结果)留到最后,因为为了显示记录,我们需要弄清楚一些事情。我还认为最好在页面顶部结果之前创建和显示导航链接。

此时,我们需要弄清楚几件事:我们的搜索是否有结果,如果有,我们有多少页结果?

结果的存在很容易通过检查记录计数来确定(请注意,我们不再拥有 EOF 属性)

If nRecCount = 0 Then
    ... ' Clean up
    ... ' Do the no results HTML here
    Response.Write("No Items found.")
    Response.End 
    ... ' Done
End If

页数显然取决于我们希望每页显示的项数。ADO.NET 没有我们喜欢并用于 ADO 的所有那些很酷的属性。ADO Recordset 对象的 PageSize、PageCount、AbsolutePage 属性对我们来说不再可用。我们将不得不采用一些非常简单的计算来确定我们拥有的数据页数。

nPageCount = nRecCount \ RECORDS_PER_PAGE
If nRecCount Mod RECORDS_PER_PAGE > 0 Then
	nPageCount += 1
End If

现在我们需要讨论当前页码。由于我们希望此页面(results.aspx)能够显示结果的任何一页,因此我们必须有一种方法来指定用户当前正在查看哪一页。我们将通过向我们的 results.aspx 脚本传递一个附加参数来实现,我们将其命名为“Page”。因此,到我们页面的链接可能如下所示

http://..../results.aspx?Keyword=BlahBlahBlah&Page=3

有了这些,我们就可以通过简单地检查 Page 参数来计算用户请求的页码

nPage = Convert.ToInt32(Request.QueryString("Page"))

我们需要确保用户请求的页码在可接受的范围内,并在需要时进行修复

If nPage < 1 Or nPage > nPageCount Then
	nPage = 1
End If

现在我们可以通过简单地链接到此页面并为 Keyword 和特定页码使用相同的值来创建导航链接。例如

' First page
Response.Write("<A HREF=""results.aspx?Keyword=" & Keyword & "&Page=1"">First Page</A>")
' Previous page
Response.Write("<A HREF=""results.aspx?Keyword=" & Keyword & "&Page=" & (nPage - 1).ToString() & """>Prev. Page</A>")
' Next page
Response.Write("<A HREF=""results.aspx?Keyword=" & Keyword & "&Page=" & (nPage + 1).ToString() & """>Next Page</A>")
' Last page
Response.Write("<A HREF=""results.aspx?Keyword=" & Keyword & "&Page=" & nPageCount.ToString() & """>Last Page</A>"
' 15th page
Response.Write("<A HREF=""results.aspx?Keyword=" & Keyword & "&Page=15"">15th Page</A>")

我的示例脚本中提供了另一种提供导航链接的方式。

3. 显示一页结果

我们剩下要做的就是显示一页结果。

但在这样做之前,我们需要找出这一页的起始和结束行(记录)的索引。

nStart = RECORDS_PER_PAGE * (nPage - 1)
nEnd = nStart + RECORDS_PER_PAGE - 1
If nEnd > nRecCount - 1 Then
	nEnd = nRecCount - 1
End If

现在我们可以输出一页记录了。与 ADO 不同,在使用 ADO.NET 时,我们不应使用 While 循环。我们已经知道要显示的记录的索引,因此 For 循环会非常方便。

For i = nStart To nEnd
	Response.Write(DT.Rows(i)("ItemName") & "<br>")
Next

就是这样。我在这里包含的示例有点复杂,因为我将 HTML 搜索表单和结果显示结合到了一个页面中。这就是为什么在每个链接中都使用了额外的 **Mode** 参数。所有关于显示搜索结果的代码都在 **ShowResults()** 函数中。

© . All rights reserved.