数据库、GridView 分页的问题??
我在使用 GridView 时 ,我设置了 GridView 分页相关属性,我想问下 ,如下情况 :
比如 ,我 select 某表 ,一共得到 1000000 条数据 ,这时 GridView 就分页显示了 。
那这时 ,我想问 :
情况一 : 1000000 条数据都到了客户端 ,然后再 GridView 分页显示 。
情况二 : 数据分批到达客户端 ,GridView 显示第一页时 ,第一页的数据从服务器到达客户端 ;GridView 显示第二页时 ,第二页的数据从服务器到达客户端 ;GridView 显示第三页时 ,第三页的数据从服务器到达客户端 ;......
请问是哪种情况??
如果是第二种情况的话,要自己写分页算法??有好的分页算法推荐下(链接啥的都可)??
[解决办法]
分页英爱查询需要的数据,然后绑定到Gridview
比如你每页20条记录,那么第一页就该查询第1-20条,第二页就该查询第21-40条,以此类推。
根据查询返回的记录重新绑定Gridview.
[解决办法]
第二种,按需取数据,张永资源小速度快----使用分页控件比较方便
[解决办法]
肯定要用情况二了,一次性加载那么多数据性能肯定不高,分页算法代码都差不多,总记录数,当前页码,每页显示记录数网上很多,直接写一个存储过程就好了,要分页的时候就调写好的过程就OK了。
[解决办法]
可以使用分页控件,网上有很多,主流的就是aspnetpager 控件,功能较全
[解决办法]
程序代码
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Clear
-- Create date: 2007-01-30
-- Description: 高性能分页
-- =============================================
Alter PROCEDURE [dbo].[Tag_Page_Name_Select]
-- 传入最大显示纪录数和当前页码
@MaxPageSize int,
@PageNum int,
-- 设置一个输出参数返回总纪录数供分页列表使用
@Count int output
AS
BEGIN
SET NOCOUNT ON;
DECLARE
-- 定义排序名称参数
@Name nvarchar(50),
-- 定义游标位置
@Cursor int
-- 首先得到纪录总数
Select @Count = count(tag_Name)
FROM [viewdatabase0716].[dbo].[view_tag];
-- 定义游标需要开始的位置
Set @Cursor = @MaxPageSize*(@PageNum-1)+1
-- 如果游标大于纪录总数将游标放到最后一页开始的位置
IF @Cursor > @Count
BEGIN
-- 如果最后一页与最大每次纪录数相等,返回最后整页
IF @Count % @MaxPageSize = 0
BEGIN
IF @Cursor > @MaxPageSize
Set @Cursor = @Count - @MaxPageSize + 1
ELSE
Set @Cursor = 1
END
-- 否则返回最后一页剩下的纪录
ELSE
Set @Cursor = @Count - (@Count % @MaxPageSize) + 1
END
-- 将指针指到该页开始
Set Rowcount @Cursor
-- 得到纪录开始的位置
Select @Name = tag_Name
FROM [viewdatabase0716].[dbo].[view_tag]
orDER BY tag_Name;
-- 设置开始位置
Set Rowcount @MaxPageSize
-- 得到该页纪录
Select *
From [viewdatabase0716].[dbo].[view_tag]
Where tag_Name >= @Name
order By tag_Name
Set Rowcount 0
END
然后是分页控件(... 为省略的生成HTML代码方法):
程序代码
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Text;
/// <summary>
/// 扩展连接字符串
/// </summary>
public class ExStringBuilder
{
private StringBuilder InsertString;
private StringBuilder PageString;
private int PrivatePageNum = 1;
private int PrivateMaxPageSize = 25;
private int PrivateMaxPages = 10;
private int PrivateCount;
private int PrivateAllPage;
public ExStringBuilder()
{
InsertString = new StringBuilder("");
}
/// <summary>
/// 得到生成的HTML
/// </summary>
public string GetHtml
{
get
{
return InsertString.ToString();
}
}
/// <summary>
/// 得到生成的分页HTML
/// </summary>
public string GetPageHtml
{
get
{
return PageString.ToString();
}
}
/// <summary>
/// 设置或获取目前页数
/// </summary>
public int PageNum
{
get
{
return PrivatePageNum;
}
set
{
if (value >= 1)
{
PrivatePageNum = value;
}
}
}
/// <summary>
/// 设置或获取最大分页数
/// </summary>
public int MaxPageSize
{
get
{
return PrivateMaxPageSize;
}
set
{
if (value >= 1)
{
PrivateMaxPageSize = value;
}
}
}
/// <summary>
/// 设置或获取每次显示最大页数
/// </summary>
public int MaxPages
{
get
{
return PrivateMaxPages;
}
set
{
PrivateMaxPages = value;
}
}
/// <summary>
/// 设置或获取数据总数
/// </summary>
public int DateCount
{
get
{
return PrivateCount;
}
set
{
PrivateCount = value;
}
}
/// <summary>
/// 获取数据总页数
/// </summary>
public int AllPage
{
get
{
return PrivateAllPage;
}
}
/// <summary>
/// 初始化分页
/// </summary>
public void Pagination()
{
PageString = new StringBuilder("");
//得到总页数
PrivateAllPage = (int)Math.Ceiling((decimal)PrivateCount / (decimal)PrivateMaxPageSize);
//防止上标或下标越界
if (PrivatePageNum > PrivateAllPage)
{
PrivatePageNum = PrivateAllPage;
}
//滚动游标分页方式
int LeftRange, RightRange, LeftStart, RightEnd;
LeftRange = (PrivateMaxPages + 1) / 2-1;
RightRange = (PrivateMaxPages + 1) / 2;
if (PrivateMaxPages >= PrivateAllPage)
{
LeftStart = 1;
RightEnd = PrivateAllPage;
}
else
{
if (PrivatePageNum <= LeftRange)
{
LeftStart = 1;
RightEnd = LeftStart + PrivateMaxPages - 1;
}
else if (PrivateAllPage - PrivatePageNum < RightRange)
{
RightEnd = PrivateAllPage;
LeftStart = RightEnd - PrivateMaxPages + 1;
}
else
{
LeftStart = PrivatePageNum - LeftRange;
RightEnd = PrivatePageNum + RightRange;
}
}
//生成页码列表统计
PageString.Append(...);
StringBuilder PreviousString = new StringBuilder("");
//如果在第一页
if (PrivatePageNum > 1)
{
...
}
else
{
...
}
//如果在第一组分页
if (PrivatePageNum > PrivateMaxPages)
{
...
}
else
{
...
}
PageString.Append(PreviousString);
//生成中间页
for (int i = LeftStart; i <= RightEnd; i++)
{
//为当前页时
if (i == PrivatePageNum)
{
...
}
else
{
...
}
}
StringBuilder LastString = new StringBuilder("");
//如果在最后一页
if (PrivatePageNum < PrivateAllPage)
{
...
}
else
{
...
}
//如果在最后一组
if ((PrivatePageNum + PrivateMaxPages) < PrivateAllPage)
{
...
}
else
{
...
}
PageString.Append(LastString);
}
/// <summary>
/// 生成Tag分类表格
/// </summary>
public void TagTable(ExDataRow myExDataRow)
{
InsertString.Append(...);
}
调用方法:
程序代码
//得到分页设置并放入Session
ExRequest myExRequest = new ExRequest();
myExRequest.PageSession("Tag_", new string[] { "page", "size" });
//生成Tag分页
ExStringBuilder Tag = new ExStringBuilder();
//设置每次显示多少条纪录
Tag.MaxPageSize = Convert.ToInt32(Session["Tag_size"]);
//设置最多显示多少页码
Tag.MaxPages = 9;
//设置当前为第几页
Tag.PageNum = Convert.ToInt32(Session["Tag_page"]);
string[][] myNamenValue = new string[2][]{
new string[]{"MaxPageSize","PageNum","Count"},
new string[]{Tag.MaxPageSize.ToString(),Tag.PageNum.ToString()}
};
//调用存储过程
DataTable myDataTable = mySQL.BatchGetDB("Tag_Page_Name_Select", myNamenValue, "Count");
Tag.DateCount = (int)mySQL.OutputCommand.Parameters["@Count"].Value;
Tag.Pagination();
HeadPage.InnerHtml = FootPage.InnerHtml = Tag.GetPageHtml;
for (int i = 0, j = myDataTable.Rows.Count; i < j; i++)
{
Tag.TagTable(new ExDataRow(myDataTable.Rows[i]));
}
TagBox.InnerHtml = Tag.GetHtml;
处理页码到Session的方法就不提供了,没有很大关.调用存储过程返回参数和纪录的方法和之前我写的批量数据操作方法差不多的,只需要定义一个输出方式.
目前我想这些代码还会有瑕疵,等项目后期代码审查的时候再强化吧,我想说的一点就是不要被那些拖来拖去的东西迷惑了,那样对自己永远都没有提高,要抱着知其然,知其所以然的态度去做一件事情,对自己的帮助才会明显.
这个方法已经通过测试 可以试试
[解决办法]
- C# code
//1 在Gridview编辑模版,在PagerTemplate中加入如下的table内容(注意复制的时候别把<PagerTemplate></PagerTemplate>复制进去) <PagerTemplate> <table width="100%" style="font-size:12px;"> <tr> <td style="text-align: right"> 第<asp:Label ID="lblPageIndex" runat="server" Text='<%# ((GridView)Container.Parent.Parent).PageIndex + 1 %>'></asp:Label> 页 /共<asp:Label ID="lblPageCount" runat="server" Text='<%# ((GridView)Container.Parent.Parent).PageCount %>'></asp:Label> 页 <asp:LinkButton ID="btnFirst" runat="server" CausesValidation="False" CommandName="Page" Text="首页" CommandArgument="first" OnClick="btnFirst_Click"> </asp:LinkButton> <asp:LinkButton ID="btnPrev" runat="server" CausesValidation="False" CommandName="Page" Text="上一页" CommandArgument="prev" onclick="btnFirst_Click"> </asp:LinkButton> <asp:LinkButton ID="btnNext" runat="server" CausesValidation="False" CommandName="Page" Text="下一页" CommandArgument="next" OnClick="btnFirst_Click"> </asp:LinkButton> <asp:LinkButton ID="btnLast" runat="server" CausesValidation="False" CommandName="Page" Text="尾页" CommandArgument="last" OnClick="btnFirst_Click"> </asp:LinkButton> <asp:TextBox ID="txtNewPageIndex" runat="server" Text='' Width="20px" AutoPostBack="False" ontextchanged="txtNewPageIndex_TextChanged"></asp:TextBox> <asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server" ControlToValidate="txtNewPageIndex" Display="Dynamic" ErrorMessage="请输入正整数!" ValidationExpression="^([0-9]*)$"></asp:RegularExpressionValidator> <asp:LinkButton ID="btnGo" runat="server" CausesValidation="False" CommandArgument="go" CommandName="Page" Text="GO" OnClick="btnFirst_Click"></asp:LinkButton> </td> </tr> </table> </PagerTemplate>//2在上一页按钮中加入如下代码(注意GVInfo就是Gridview控件) protected void btnFirst_Click(object sender, EventArgs e) { switch (((LinkButton)sender).CommandArgument.ToString()) { case "first": GVInfo.PageIndex = 0; break; case "last": GVInfo.PageIndex = GVInfo.PageCount - 1; break; case "prev": if (GVInfo.PageIndex != 0) { GVInfo.PageIndex = GVInfo.PageIndex - 1; } else { Response.Write("<script>alert('已经是第1页了!');location='AllInfo.aspx'</script>"); } break; case "next": if (GVInfo.PageIndex != GVInfo.PageCount-1) { GVInfo.PageIndex = GVInfo.PageIndex + 1; } else { Response.Write("<script>alert('已经是最后1页了!');location='AllInfo.aspx'</script>"); } break; case "go": { GridViewRow gvr = GVInfo.BottomPagerRow; TextBox temp = (TextBox)gvr.FindControl("txtNewPageIndex"); int res = Convert.ToInt32(temp.Text.ToString()); GVInfo.PageIndex = res - 1; } break; } AllInfoBind();//AllInfoBind你的数据绑定方法,根据需要重新绑定数据源至GridView控件。 }
[解决办法]
- C# code
public DataSet GetListByPage(string strWhere, string orderby, int startIndex, int endIndex) { StringBuilder strSql = new StringBuilder(); strSql.Append("SELECT * FROM ( "); strSql.Append(" SELECT ROW_NUMBER() OVER ("); if (!string.IsNullOrEmpty(orderby.Trim())) { strSql.Append("order by T." + orderby); } else { strSql.Append("order by T.f_tableid desc"); } strSql.Append(")AS Row, T.* from t_table T "); if (!string.IsNullOrEmpty(strWhere.Trim())) { strSql.Append(" WHERE " + strWhere); } strSql.Append(" ) TT"); strSql.AppendFormat(" WHERE TT.Row between {0} and {1}", startIndex, endIndex); return DbHelperOleDb.Query(strSql.ToString()); }