WorldofASP.NET : ASP.NET Directory, Tutorial, Hosting, and Source Code
You are 1 of 90 users


WorldofASP.NET >> ASP.NET >> Database

Improve Your DataGrid Paging performance

Tips and tricks on how to improve your DataGrid Paging performance
Published Date : 04 Dec 2007
Author : James Douglas
Language : VB.NET,C#
Platform : .NET
Technology : None,Visual Studio,ASP.NET
Views : 8478
Rating : (3 votes so far)



Introduction

If you are experiencing performance bottleneck on your web applications running DataGrid or GridView paging, then this article can help you to improve  the performance of your website. You probably know that implement paging in DataGrid or GridView can be done in very few lines of code. But this comes with the price. As if you deploy the site into production server with thousands of data, then you can start feel that instantly. You probably ask the reason why?.

The reason is because everytime when you navigate from page to page, the DataGrid actually rebind to the DataSet or DataTable and the DataTable will load the entire record into it and then display a small subset of the data into your grid. So regardless of whether you are navigating page 1 or page 2, you can see the amount of time it take will be the same.

Building Custom Paging with Numbering for Your DataGrid or GridView

The solution to overcome this issue, is to write your own custom paging method into your DataGrid or GridView. Since we are writing custom Paging, we will be including the numbering features for the Paging. So instead of navigating through the Next and Previous button, the user can jump to any page that he like.This is a nice features just like what you can see in Google or Yahoo.



For this article, we will be using  the Sample Northwind Database. If you don't have the database, you can do a search from Google to download it.

Create New Aspx Page and named it GridViewPaging.aspx
Copy and Paste the code below.

<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" WIDTH="100%" CLASS="TablePager">
<TR>
<TD COLSPAN="3">
<ASP:GRIDVIEW ID="GridView1" RUNAT="server">
</ASP:GRIDVIEW>
</TD>
</TR>
<TR>
<TD COLSPAN="3">
<HR />
</TD>
</TR>
<TR>
<TD ALIGN="left" WIDTH="100px">
<ASP:LABEL ID="lblPrev" RUNAT="server"></ASP:LABEL></TD>
<TD ALIGN="center">
<ASP:LABEL ID="lblPageNoFooter" RUNAT="server"></ASP:LABEL>
</TD>
<TD ALIGN="right" WIDTH="100px">
<ASP:LABEL ID="lblNext" RUNAT="server"></ASP:LABEL>
</TD>
</TR>
</TABLE>
From the code above, you can see that we just drag the GridView control and we put few label for navigating between the next, previous and the page counter to show the current page.

Next, we will be building the Stored Procedures that will only retrieve portion of the data that we need.
I basically grab this stored procedures from this article here. If you need further explanation about the stored procedures, then please refer to this article.

CREATE PROCEDURE [dbo].[usp_PageResults_Products] 
(
@startRowIndex int,
@maximumRows int,
@totalRows int
)
AS
DECLARE @first_id int, @startRow int-- A check can be added to make sure @startRowIndex isn't > count(1)
-- from employees before doing any actual work unless it is guaranteed
-- the caller won't do that
-- Get the first employeeID for our page of records

SET ROWCOUNT @startRowIndexSELECT @first_id = productid FROM products where discontinued = 0 ORDER BY productid-- Now, set the row count to MaximumRows and get
-- all records >= @first_id

SET ROWCOUNT @maximumRowsSELECT productid,productname,discontinued from productsWHERE discontinued = 0 and productid >= @first_idORDER BY productnameSET ROWCOUNT 0Select @totalRows = COUNT(ProductID) FROM Products where discontinued = 0
For the code behind of the GridViewPaging.aspx, we need to declare this two variables on top of the page
protected int iCurrentPage;protected const int iPageSize = 10;

The iCurrentPage represents the current page of the GridView, and the iPageSize  is the total number of records displayed on each page. You can also allow the user to adjust the page size using a DropDownList, but that is not covered in this article

Next, we will be writing code for binding the GridView
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindData();
}
}
private void BindData()
{
if (Request.QueryString["Page"] != null)
{
iCurrentPage = Convert.ToInt32(Request.QueryString["Page"]);
}
else
{
iCurrentPage = 1;
}
int iStartRowIndex = ((iCurrentPage -1 ) * iPageSize) + 1;if (iStartRowIndex == 0)
{
iStartRowIndex = 1;
}
SqlConnection oConn = new SqlConnection(ConfigurationManager.AppSettings["ConnString"].Trim());
SqlCommand oCmd = oConn.CreateCommand();
oCmd.CommandText = "usp_PageResults_Products";
oCmd.CommandType = CommandType.StoredProcedure;
oCmd.Parameters.Add("@startRowIndex", SqlDbType.Int, 4).Value = iStartRowIndex;
oCmd.Parameters.Add("@maximumRows", SqlDbType.Int, 4).Value = iPageSize;
oCmd.Parameters.Add("@totalRows", SqlDbType.Int, 4).Direction = ParameterDirection.Output;
SqlDataAdapter oDa = new SqlDataAdapter(oCmd);
DataSet ds = new DataSet();
oDa.Fill(ds);
GridView1.DataSource = ds;
GridView1.DataBind();
iTotalRows = (int)oCmd.Parameters["@totalRows"].Value;
BindPaging();
}
If you see the code above, you can see that we are binding the DataGrid to the stored procedures that we created before.  The important parameter that we need to pass to the stored procedures is the @StartRowIndex and the logic for the stored proc is quite simple.

If the CurrentPage is still Page 1, then we will be passing the StartRowIndex = 1
If the CurrentPage is still Page 2, then we will be passing the StartRowIndex = 11
If the CurrentPage is still Page 3, then we will be passing the StartRowIndex = 22

Now, the last part for this entire DataGrid and GridView Project, will be writing the code for displaying the Page Numbering and Next and Previous Link Button.
private void BindPaging()
{
double iPageCount = Math.Ceiling(Convert.ToDouble(iTotalRows / iPageSize));if (lblPageNoFooter.Text.Length <= 0)
{
//Binding Page Footerfor (int i = 1; i <= iPageCount; i++)
{
if (i == iCurrentPage)
{
lblPageNoFooter.Text += " <B>" + i + " </B> ";
}
else
{
if (i == 1)
{
lblPageNoFooter.Text += " <A HREF='Default.aspx'>" + i + " </A>";
}
else
{
lblPageNoFooter.Text += " <A HREF='Default.aspx?Page=" + i + "'>" + i + " </A>";
}
}
}
}
//Binding Prev and Nextif (iPageCount > 1)
{
if (iCurrentPage != 1)
{
lblPrev.Text = " <A HREF='Default.aspx?Page=" + (iCurrentPage - 1) + "'><< Previous </A>";
}
if (iCurrentPage != iPageCount)
{
lblNext.Text = " <A HREF='Default.aspx?Page=" + (iCurrentPage + 1) + "'>Next >></A>";
}
}
else
{
lblPrev.Visible = false;
lblNext.Visible = false;
}
}

Conclusion

As you can see from the sample code above, we are building our own custom paging solutions and you can actually compare the performance between default paging provided by the .NET framework and this one. You will notice huge performance difference especially if you are retrieving thousands of data from the database.

Download Source Code




Other Related and Popular Articles :

Using Stored Procedures with MSSQL and ASP.NET 2.0
This article explain how to migrate your existing in line SQL to Stored Procedures with MSSQL and ASP.NET 2.0

Basic Introduction to ADO.NET in ASP.NET
This article provides information on programming with ADO.NET including DataSet,DataAdapter and DataReader


Author Profile : James Douglas

I work in a Software House Company in Malaysia (Kuala Lumpur) and I am MCP Certified in C# and Web Application course.
I originally started my programming in Java but later on changed to Microsoft platform because of the simplicity and ease of use.
I love .NET programming and am doing it almost every day now.

Click here to view Author Profile


How would you rate the quality of this content?
Poor Excellent

Comments

#ProductName Sort Order problem
05 Jan 2009 10:48 by : Rune Brattas

Hi,

The ProductName does not sort correctly. With following code (1) the ProductID is the sort order and it works. I have tried with following code to sort ProductName which is not working.
Please contact me if you have solution for sorting on ProductName.
Please notice I have removed the WHERE clause for test with dicouvering the page formula doesn’t work. I do not see the last page (double iPageCount = Math.Ceiling( Convert.ToDouble( iTotalRows / iPageSize ) );).

The idea is perfect but we have some issues which we have to solve..., please contact me with suggestions and solutions :)

Thank you,
Rune
RuneBrattas @ Videotron dot ca

(1) The paging for perfect on [ProductID] (Table Products ias ASC on [ProductID]) NICE!!! If [ProductID] is nvarchar it don't work...
----------------------
CREATE PROCEDURE [dbo].[usp_Products_Paging]
(
@startRowIndex int,
@maximumRows int,
@totalRows int OUTPUT
)
AS

DECLARE @first_id int
SET ROWCOUNT @startRowIndex
SELECT @first_id = [ProductID]
FROM [dbo].[Products]
ORDER BY [ProductID]

SET ROWCOUNT @maximumRows
SELECT [ProductID],[ProductName],[Discontinued]
FROM [dbo].[Products]
WHERE [ProductID] >= @first_id
ORDER BY [ProductID]

SET ROWCOUNT 0
SELECT @totalRows = COUNT([ProductID])
FROM [dbo].[Products]

======================
(2)This Doesn't work. I have tried to get right sort order through the index without no success.

CREATE PROCEDURE [dbo].[usp_Products_Paging_Index_ProductName]
(
@startRowIndex int,
@maximumRows int,
@totalRows int OUTPUT
)
AS

DECLARE @first_id int
SET ROWCOUNT @startRowIndex
SELECT @first_id = [ProductID]
FROM [dbo].[Products] WITH (INDEX(ProductName))
ORDER BY [ProductName]

SET ROWCOUNT @maximumRows
SELECT [ProductID],[ProductName],[Discontinued]
FROM [dbo].[Products] WITH (INDEX(ProductName))
WHERE [ProductID] >= @first_id
ORDER BY [ProductName]

SET ROWCOUNT 0
SELECT @totalRows = COUNT([ProductID])
F

#CREATE PROCEDURE [dbo].[usp_PageResults_Products]
28 Dec 2008 21:05 by : Rune Brattas

@totalRows int OUTPUT

#Error in example with iTotalRows
16 Mar 2008 8:12 by : Matthew

You need to define iTotalRows as protected int iTotalRows; otherwise it wont work

Leave New Comments


Article Content copyright by James Douglas
Everything else Copyright © by WorldofASP.NET 2010

Category
.NET 3.5
AJAX and ATLAS
ASP.NET
C# Programming
Classic ASP
Enterprise Systems
General .NET
VB.NET Programming
Announcements
Earn Cash by writing an article or review
For more info Click here







Legend : - Within 3 Days - Within 6 Days - Within 9 Days

Home | Add Resources | Sponsored Listings | Advertise with Us | SiteMap 1 | SiteMap 2 | Link To Us | Contact Us
© 2002-2010 Worldofasp.net ASP.NET Directory, Hosting and Tutorials | All rights reserved
Our Partners : ASP.NET Web Hosting | ASP Hosting | ASP.NET Hosting | Phone Card | Calling Card |Stock Investing