ASP.net中数据分页是由自己管理好还是由控件管理好?

  ASP.net 2.0的发布给广大Web开发人员带来了福音,特别是其中新增加的很多控件,比如GridView、FormView、DetailView等,极大地提高了开发人员的效率。然而,我曾是一名熟练的ASP开发人员,对HTML、CSS都相当熟悉,所以对这些控件的语法很是不习惯,同时,对这些控件的性能和灵活性表示怀疑。

    GridView可以非常方便的管理数据分页,只用设置几个简单的属性即可,为了了解其自动分页的性能,我做了一个测试。

    第一步,打开SQL Server Express,建立一个数据表TestPaging,如下图,id字段是主键,postdate字段默认值是当前的时间。


    第二步,向表中添加10万行数据,呵呵,数据少了看不出效果,如下图所示的SQL语句:


    第三步,测试使用服务器控件自动管理分页的性能,建立一个页面TestGridViewPaging.aspx,在页面中添加一个SqlDataSource控件和一个GridView控件,再设置几个简单的属性,不到一分钟就完工,真的是简单方便啊。如下图:

    下面是IDE自动生成的代码,我们把页面的跟踪功能打开:

 1<%@ Page Language="C#" Trace="true"%>
 2
 3<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 4
 5<script runat="server">
 6
 7
</script>
 8
 9<html xmlns="http://www.w3.org/1999/xhtml" >
10<head runat="server">
11    <title>使用控件管理数据分页</title>
12</head>
13<body>
14    <form id="form1" runat="server">
15    <div>
16        <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:AspStudyConnectionString %>"
17            SelectCommand="SELECT * FROM [TestPaging]"></asp:SqlDataSource>
18    
19    </div>
20        <asp:GridView ID="GridView1" runat="server" AllowPaging="True" AutoGenerateColumns="False"
21            DataSourceID="SqlDataSource1" PageSize="20" Width="551px">
22            <Columns>
23                <asp:BoundField DataField="id" HeaderText="id" InsertVisible="False" ReadOnly="True"
24                    SortExpression="id" />
25                <asp:BoundField DataField="subject" HeaderText="subject" SortExpression="subject" />
26                <asp:BoundField DataField="postdate" HeaderText="postdate" SortExpression="postdate" />
27            </Columns>
28            <AlternatingRowStyle BackColor="Silver" />
29        </asp:GridView>
30    </form>
31</body>
32</html>


    第四步,测试,结果发现该页面首次运行时需花时20多秒,如下图:



随便翻页,页面的运行时间都是8到9秒,如下:


    第五步,建立TestCustomPaging.aspx页面,自己编写翻页代码,直接使用ADO.net编程,数据显示使用了DataGrid控件,同时,我再页面中使用了三个隐藏控件,分别用于保存每一页的第一条记录和最后一条记录的id以及当前页号,下面测试,结果发现不管是首次显示,还是上下翻页,都不超过0.05秒,如下图:

    只有跳转到特定页面时速度稍慢,因为使用了嵌套查询,我主要是偷懒,如果使用存储过程的话,速度应该更快,如下图:


结论:使用微软提供的服务器控件,开发效率高,但是在访问数据量大的数据库时,速度非常慢,我想,该控件可能是每次访问时都将数据全部从数据库中取出,保存到内存中,如果数据量继续增加,或者访问人数增多,服务器会不会当机呢?而我自己编写的代码,每次只访问一个页面的数据,速度快,且性能不会随数据量增大而下降,更可以提供如下所示的更人性化的用户界面:

但是,我自己编写代码,从设计到调试完成,花了约2小时的时间。

开发效率: 服务器控件/自己编写代码 = 1分钟/2小时 = 1/120
运行效率: 服务器控件/自己编写代码 = 9秒/0.05秒 = 180/1

最后,我想问一下,各位有开发经验的大侠们,你们平时的开发中,是使用控件多一些,还是自己写代码多一些?

下面是我自己编写的页面的代码:

  1<%@ Page Language="C#" Trace="true" Debug="true" %>
  2<%@ Import Namespace="System.Data" %>
  3<%@ Import Namespace="System.Data.SqlClient" %>
  4
  5<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  6
  7<script runat="server">
  8    
  9    int pagecount;
 10    int curpage;
 11    int pagesize;
 12
 13    SqlConnection con;
 14    SqlCommand command;
 15    SqlDataReader dr;
 16    
 17    DataTable CreateDataTable(SqlDataReader reader)
 18    {
 19        DataTable dt = new DataTable();
 20        DataRow dr;
 21
 22        dt.Columns.Add(new DataColumn("ID"typeof(Int32)));
 23        dt.Columns.Add(new DataColumn("主题"typeof(string)));
 24        dt.Columns.Add(new DataColumn("发表时间"typeof(DateTime)));
 25
 26        while (reader.Read())
 27        {
 28            dr = dt.NewRow();
 29
 30            dr[0= reader.GetInt32(0);
 31            dr[1= reader.GetString(1);
 32            dr[2= reader.GetDateTime(2);
 33
 34            dt.Rows.Add(dr);
 35        }

 36        return dt;
 37    }

 38
 39    void SaveIndex(DataTable dt)
 40    {
 41        int rowcount = dt.Rows.Count;
 42        DataRow firstrow = dt.Rows[0];
 43        DataRow lastrow = dt.Rows[rowcount - 1];
 44        int minid = (int)firstrow[0];
 45        int maxid = (int)lastrow[0];
 46        if (maxid > minid)
 47        {
 48            minidctl.Value = minid.ToString();
 49            maxidctl.Value = maxid.ToString();
 50        }

 51        else
 52        {
 53            maxidctl.Value = minid.ToString();
 54            minidctl.Value = maxid.ToString();
 55        }

 56    }

 57
 58    
 59    void Page_Load()
 60    {
 61        pagesize = 20;
 62        con = new SqlConnection(@"Data Source=XIELAOSAN\SQLEXPRESS;Initial Catalog=AspStudy;User ID=xielaosan;Password=811116");
 63        command = new SqlCommand();
 64        command.Connection = con;
 65        con.Open();
 66        
 67        if (!IsPostBack)
 68        {
 69            command.CommandText = "select top " + pagesize + " * from TestPaging";
 70            dr = command.ExecuteReader();
 71            DataTable dt = CreateDataTable(dr);
 72            data1.DataSource = dt;
 73            data1.DataBind();
 74            dr.Close();
 75            //获取该页面上的最大id和最小id,保存到隐藏控件中
 76            SaveIndex(dt);
 77        }

 78        //设置总页数和当前页数
 79        command.CommandText = "select count(id) from TestPaging";
 80        dr = command.ExecuteReader();
 81        dr.Read();
 82        int recordcount = dr.GetInt32(0);
 83        pagecount = (recordcount-1-((recordcount-1)%pagesize))/pagesize + 1;
 84        lblTotalPage.Text = "当前是第1页/" + "总共" + pagecount + "";
 85        dr.Close();
 86        curpage = Int32.Parse(curpagectl.Value);
 87    }

 88
 89    protected void btnNext_Click(object sender, EventArgs e)
 90    {
 91        int minid = Int32.Parse(minidctl.Value);
 92        int maxid = Int32.Parse(maxidctl.Value);
 93        command.CommandText = "select top 20 * from TestPaging where id>" + maxid + "";
 94        dr = command.ExecuteReader();
 95        DataTable dt = CreateDataTable(dr);
 96        data1.DataSource = dt;
 97        data1.DataBind();
 98        dr.Close();
 99        //获取该页面上的最大id和最小id,保存到隐藏控件中
100        SaveIndex(dt);
101        //保存当前页标号
102        curpage ++;
103        curpagectl.Value = curpage.ToString();
104        if (curpage >= pagecount)
105        {
106            btnNext.Visible = false;
107            btnLast.Visible = false;
108        }

109        else
110        {
111            btnNext.Visible = true;
112            btnLast.Visible = true;           
113        }

114        if (curpage <= 1)
115        {
116            btnFirst.Visible = false;
117            btnPrev.Visible = false;
118        }

119        else
120        {
121            btnFirst.Visible = true;
122            btnPrev.Visible = true;
123        }

124        lblTotalPage.Text = "当前是第" + curpage + "页/" + "总共" + pagecount + "";
125    }

126
127    protected void btnLast_Click(object sender, EventArgs e)
128    {
129        int minid = Int32.Parse(minidctl.Value);
130        int maxid = Int32.Parse(maxidctl.Value);
131        command.CommandText = "select top 20 * from TestPaging order by id desc";
132        dr = command.ExecuteReader();
133        DataTable dt = CreateDataTable(dr);
134        DataView dv = new DataView(dt);
135        dv.Sort = "id";
136        data1.DataSource = dv;
137        data1.DataBind();
138        dr.Close();
139        //获取该页面上的最大id和最小id,保存到隐藏控件中
140        SaveIndex(dt);
141        //保存当前页标号
142        curpage = pagecount;
143        curpagectl.Value = curpage.ToString();
144        if (curpage <= 1)
145        {
146            btnFirst.Visible = false;
147            btnPrev.Visible = false;
148        }

149        else
150        {
151            btnFirst.Visible = true;
152            btnPrev.Visible = true;
153        }

154        if (curpage >= pagecount)
155        {
156            btnNext.Visible = false;
157            btnLast.Visible = false;
158        }

159        else
160        {
161            btnNext.Visible = true;
162            btnLast.Visible = true;
163        }

164        lblTotalPage.Text = "当前是第" + curpage + "页/" + "总共" + pagecount + "";
165    }

166
167    protected void btnPrev_Click(object sender, EventArgs e)
168    {
169        int minid = Int32.Parse(minidctl.Value);
170        int maxid = Int32.Parse(maxidctl.Value);
171        command.CommandText = "select top 20 * from TestPaging where id<" + minid + " order by id desc";
172        dr = command.ExecuteReader();
173        DataTable dt = CreateDataTable(dr);
174        DataView dv = new DataView(dt);
175        dv.Sort = "id";
176        data1.DataSource = dv;
177        data1.DataBind();
178        dr.Close();
179        //获取该页面上的最大id和最小id,保存到隐藏控件中
180        SaveIndex(dt);
181        //保存当前页标号
182        curpage --;
183        curpagectl.Value = curpage.ToString();
184        if (curpage <=1)
185        {
186            btnFirst.Visible = false;
187            btnPrev.Visible = false;
188        }

189        else
190        {
191            btnFirst.Visible = true;
192            btnPrev.Visible = true;
193        }

194        if (curpage >= pagecount)
195        {
196            btnNext.Visible = false;
197            btnLast.Visible = false;
198        }

199        else
200        {
201            btnNext.Visible = true;
202            btnLast.Visible = true;
203        }

204        lblTotalPage.Text = "当前是第" + curpage + "页/" + "总共" + pagecount + "";
205    }

206
207    protected void btnFirst_Click(object sender, EventArgs e)
208    {
209        int minid = Int32.Parse(minidctl.Value);
210        int maxid = Int32.Parse(maxidctl.Value);
211        command.CommandText = "select top 20 * from TestPaging order by id asc";
212        dr = command.ExecuteReader();
213        DataTable dt = CreateDataTable(dr);
214        data1.DataSource = dt;
215        data1.DataBind();
216        dr.Close();
217        //获取该页面上的最大id和最小id,保存到隐藏控件中
218        SaveIndex(dt);
219        //保存当前页标号
220        curpage = 1;
221        curpagectl.Value = curpage.ToString();
222        if (curpage >= pagecount)
223        {
224            btnNext.Visible = false;
225            btnLast.Visible = false;
226        }

227        else
228        {
229            btnNext.Visible = true;
230            btnLast.Visible = true;
231        }

232        if (curpage <= 1)
233        {
234            btnFirst.Visible = false;
235            btnPrev.Visible = false;
236        }

237        else
238        {
239            btnFirst.Visible = true;
240            btnPrev.Visible = true;
241        }

242        lblTotalPage.Text = "当前是第" + curpage + "页/" + "总共" + pagecount + "";
243
244    }

245
246    protected void btnJumpToPage_Click(object sender, EventArgs e)
247    {
248        int minid = Int32.Parse(minidctl.Value);
249        int maxid = Int32.Parse(maxidctl.Value);
250        int pagenum = Int32.Parse(txtPageNum.Text);
251        if (pagenum > 1 && pagenum <pagecount)
252        {
253
254            command.CommandText = "select top 20 * from TestPaging where id>"
255                + "(select max(id) from TestPaging where id in "
256                + "(select top " + pagesize * (pagenum - 1+ " id from TestPaging as temptable))";
257            dr = command.ExecuteReader();
258            DataTable dt = CreateDataTable(dr);
259            data1.DataSource = dt;
260            data1.DataBind();
261            dr.Close();
262            //获取该页面上的最大id和最小id,保存到隐藏控件中
263            SaveIndex(dt);
264            //保存当前页标号
265            curpage = pagenum;
266            curpagectl.Value = curpage.ToString();
267            if (curpage >= pagecount)
268            {
269                btnNext.Visible = false;
270                btnLast.Visible = false;
271            }

272            else
273            {
274                btnNext.Visible = true;
275                btnLast.Visible = true;
276            }

277            if (curpage <= 1)
278            {
279                btnFirst.Visible = false;
280                btnPrev.Visible = false;
281            }

282            else
283            {
284                btnFirst.Visible = true;
285                btnPrev.Visible = true;
286            }

287            lblTotalPage.Text = "当前是第" + curpage + "页/" + "总共" + pagecount + "";
288        }

289    }

290
</script>
291
292<html xmlns="http://www.w3.org/1999/xhtml" >
293<head runat="server">
294    <title>Untitled Page</title>
295</head>
296<body>
297    <form id="form1" runat="server">
298    <div>
299    <asp:DataGrid runat=server ID="data1"></asp:DataGrid><br />
300        &nbsp;<asp:HiddenField ID="minidctl" runat="server" />
301        <asp:HiddenField ID="maxidctl" runat="server" />
302        <asp:HiddenField ID="curpagectl" runat="server" Value="1" />
303        <asp:Label ID="lblTotalPage" runat="server" Text="Label"></asp:Label>
304        <asp:Button ID="btnFirst" runat="server" Text="首页" OnClick="btnFirst_Click" />
305        <asp:Button ID="btnPrev" runat="server" Text="上一页" OnClick="btnPrev_Click" />
306        <asp:Button ID="btnNext" runat="server" OnClick="btnNext_Click" Text="下一页" />
307        <asp:Button ID="btnLast" runat="server" Text="尾页" OnClick="btnLast_Click" />
308        <asp:Label ID="Label2" runat="server" Text="跳转到"></asp:Label>
309        <asp:TextBox ID="txtPageNum" runat="server" Height="12px" Width="16px"></asp:TextBox>
310        <asp:Label ID="Label3" runat="server" Text="页"></asp:Label>
311        <asp:Button ID="btnJumpToPage" runat="server" Text="Go" OnClick="btnJumpToPage_Click" /></div>
312    </form>
313</body>
314</html>
315
posted @ 2006-08-17 14:50  翅膀  阅读(219)  评论(0)    收藏  举报