Library tutorials & articles

Custom ASP.NET Datagrid Paging With Exact Count

Accessing our Data

The first step is of course to query our database, and send our data into our datagrid. The first thing we should concern ourselves with in any .Net page is that we import the necessary namespaces for our app. In this case, as with most data access apps, I'm importing System.Data and System.Data.SqlClient for SQL Server. If you use MS Access or another database then System.Data.OleDb namespace and associated classes will work just fine, providing you modify the connection variables and data adapters.

This importing of namespaces is all done before our script tags like so:

<%@ Import Namespace = "System.Data" %>
<%@ Import Namespace = "System.Data.SqlClient" %>

Now, within our server-side script tags we include our object-oriented stuff – our Subroutine to access our database and bind our result set into our ASP.NET Datagrid. This subroutine, BindSQL() needs to first create all of our variables that we'll use:

Sub BindSQL()
    Dim MyConnection As SqlConnection
    Dim DS as DataSet
    Dim MyCommand As SqlDataAdapter
    Dim RcdCount As Integer

    'Our SQL string
    Dim sqlStr As String = "SELECT titles.title, authors.au_lname, " & _
        "authors.au_fname, titles.price " & _
        "FROM authors INNER JOIN titleauthor ON " & _
        "authors.au_id = titleauthor.au_id " & _
        "INNER JOIN titles ON " & _
        "titleauthor.title_id = titles.title_id"

    'The connection to our database
    Dim strConn As String = "server=(local);uid=sa;pwd=;" & _
        "database=pubs;Trusted_Connection=yes;"

Next we need to instantiate our connection and command object, and the fill our DataSet object with the results of the SQL query:

    ...

    'Open up our connection with our connection object
    MyConnection = New SQLConnection(strConn)

    'To execute our Sql Statement and provide our active connection
    MyCommand = NewSqlDataAdapter(sqlStr, MyConnection)

    'Create instance of DataSet object and fill our predetermined
    'datagrid with it and we name it
    DS = new DataSet()
    MyCommand.Fill(DS, "pubs")

    ...

Now comes the one part that we'll used for our custom paging – the record count, and you'll see it quite different than our classic ASP way.

RcdCount = DS.Tables("pubs").Rows.Count.ToString()

Now that we have this total count of the records in the DataSet, we'll save it to a global variable, since we'll want to access it from other subroutines. The variable ResultCount should be defined in global-scope, as an Integer. (See the complete source later on in this article to note how to create global-scoped variables)

ResultCount = RcdCount

Next, we display the number of records found in a label control:

RecordCount.Text = "<b><font color=red>" & RcdCount & "</font> records found"

Finally, at this point, we can bind our DataSet to the DataGrid and display a label illustrating what page of results we're currently viewing, which will display :

Pubs.DataSource = DS
Pubs.Databind()

lblPageCount.Text = "Page " & Pubs.CurrentPageIndex + 1 & " of " & Pubs.PageCount

At this point, we need to determine if we need to show the Next/Prev links, as well as the First Page/Last Page links:

'Do we want to show the prev/First Page buttons?
If Pubs.CurrentPageIndex <> 0 Then
    Call Prev_Buttons()
    Firstbutton.Visible = true
    Prevbutton.Visible = true
Else
    Firstbutton.Visible = false
    Prevbutton.Visible = false
End If

'Do we want to show the Next/Last Page buttons?
If Pubs.CurrentPageIndex <> (Pubs.PageCount-1) then
    Call Next_Buttons()
    NextButton.Visible = true
    Lastbutton.Visible = true
Else
    NextButton.Visible = false
    Lastbutton.Visible = False
End If

End Sub

That concludes our BindSQL() subroutine, which is a bit lengthy. Don't worry, that's, by far, the most complex piece of our ASP.NET Web page! We still have three more short server-side subroutines to examine, but let's first look at the HTML portion of our ASP.NET Web page, which we'll do on the next page.

Comments

  1. 08 Jul 2005 at 17:18

    Hi, thanks, I appreciate your compliments.


    I have written another older article that I think should help. It's entitled- Drilldown Datagrid Searching with ASP.NET.


    This article demonstrates how to do a standard search, display the results in a datagrid, then further filter and search the datagrid itself and drilldown into the datagrid results themselves.


    So to merge the two, work off of the aforementioned article and incorporate the custom paging. All this should be no problem, and plenty to get you up and running.


    Also, for scalability purposes, read another article of mine here on DF - .NET Data Caching . Between the two you'll be able to provide some great functionality and performance.


    I hope this helps!


    - Jimmy Markatos

  2. 08 Jul 2005 at 15:56

    I loved your article on custom paging but would very much like to know how to apply it when you filter your initial data set to retreive specific records. I have a grid with 813 records sorted by user name. I have a search box in which a user can enter a name in order to filter the original dataset. If the search result in only 4 pages of records how can I page through that new set of records? Thanks in advance for any help and for the great article.

  3. 26 Oct 2003 at 20:00

    Check this site...


    I too was on the same quest and I've created a best practices reference site that covers many enterprise topics necessary to create large scale enterprise sites.

  4. 17 Oct 2003 at 05:38
    Hello,

    Tankete, I just have try what you are asking for a couple of days ago :

    The principe is simple : returning only a needed page from 50th to 60th records consists in querying this way :

    SELECT * TOP 60 ... WHERE NOT IN SELECT TOP 50 * WHERE [joining primarykeys]

    I have taken advices from Dino Esposito's MSDN articles, and have created a PageQuery function thats returns such a SQL statement, based on a normal SQL statement, primaryKey information, currentpageindex and pagesize.

    This sample of code uses a custompaged enabled datagrid called dg, with a access database that contains a "HugeTable" table with a "ID" primary key.

    Do not forget to enable custompaging to your datagrid

    Code:


       Private _Cx As OleDbConnection

       Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

           _Cx = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Password="""";User ID=Admin;Data Source=C:\Inetpub\wwwroot\labo\app\db\paged_datagrid.mdb;Mode=Share Deny None;")

           If Not IsPostBack Then
               dg.DataBind()
               DataList1.DataBind()
           End If

       End Sub

       '

       Private Sub dg_DataBinding(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles dg.DataBinding

           Dim sqlstr As String = PageQuery("SELECT * FROM HugeTable ORDER BY ID", "ID", dg.CurrentPageIndex, dg.PageSize)
           _Cx.Open()

           dg.VirtualItemCount = New OleDbCommand("SELECT COUNT(*) FROM HugeTable", _Cx).ExecuteScalar
           Dim dr As OleDbDataReader = New OleDbCommand(sqlstr, _Cx).ExecuteReader(CommandBehavior.CloseConnection)
           dg.DataSource = dr

       End Sub

       '
       '
       Private Function PageQuery(ByVal commandText As String, _
                                  ByVal primaryKey As String, _
                                  ByVal currentPageIndex As Integer, _
                                  ByVal pageSize As Integer) As String

           Dim SubQuery1_TopCount As Integer = IIf(currentPageIndex = 0, _
                                                   pageSize, _
                                                   currentPageIndex * pageSize + pageSize)

           Dim SubQuery1 As String = Replace(commandText, _
                                             "SELECT ", _
                                             String.Format("SELECT TOP {0} ", SubQuery1_TopCount))

           If currentPageIndex = 0 Then Return SubQuery1

           SubQuery1 = String.Format("({0}) AS T1", SubQuery1)

           Dim SubQuery2_TopCount As Integer = currentPageIndex * pageSize

           Dim SubQuery2 As String = Replace(commandText, _
                                             "SELECT ", _
                                             String.Format("SELECT TOP {0} ", SubQuery2_TopCount))

           SubQuery2 = String.Format("({0}) AS T2", SubQuery2)

           Dim MainQuery As String = String.Format("SELECT t1.* FROM {0} LEFT JOIN {1} ON T1.{2}= T2.{2} WHERE T2.{2} IS NULL", _
                                                   SubQuery1, _
                                                   SubQuery2, _
                                                   primaryKey)

           Return MainQuery

       End Function

       '

       Private Sub dg_PageIndexChanged(ByVal source As System.Object, ByVal e As System.Web.UI.WebControls.DataGridPageChangedEventArgs) Handles dg.PageIndexChanged
           dg.CurrentPageIndex = e.NewPageIndex
           dg.DataBind()
       End Sub



    Hope it helps. For SQL server, the built query could be better implemented using subqueries instead of inner join, which is much more faster in access.

    Laurent.
  5. 16 Oct 2003 at 14:58
    I was hoping that you would address how to do paging with exact counts while NOT returning the entire dataset from the database, just the current page worth of data. Can you provide any information on how you would accomplish that? The current approach that I can think of does not perform as well as desired.
  6. 01 Jan 1999 at 00:00

    This thread is for discussions of Custom ASP.NET Datagrid Paging With Exact Count.

Leave a comment

Sign in or Join us (it's free).

Dimitrios Markatos Dimitrios, or Jimmy as his friends call him, is a .NET developer/architect who specializes in Microsoft Technologies for creating high-performance and scalable data-driven enterprise Web and deskto...

Related podcasts

Events coming up

  • Mar 15

    DevWeek 2010

    London, United Kingdom

    DevWeek is Europe’s leading independent conference for software developers, database professionals and IT architects, and features expert speakers on a wide range of topics, including .NET 4.0, Silverlight 3, WCF 4, Visual Studio 2010, REST, Windows Workflow 4, Thread Synchronization, ASP.NET 4.0, SQL Server 2008 R2, LINQ, Unit Testing, CLR & C# 4.0, .NET Patterns, WPF 4, F#, Windows Azure, ADO.NET, Entity Framework, Debugging, T-SQL Tips & Tricks, and more.

We'd love to hear what you think! Submit ideas or give us feedback