Click here to Skip to main content
Click here to Skip to main content

Using Linq to paginate your ObjectDataSource.

, 18 Mar 2008
Rate this:
Please Sign up or sign in to vote.
In this article I walk through an example that binds a gridview control to an ObjectDataSource and uses Linq queries to paginate to achieve true data pagination.

Introduction

rownum

When SQL server 2005 first launched I wrote about using ROW_NUMBER() to paginate your data with SQL Server 2005. Today I am going to look at an alternate approach on the same subject. In this article I will review data pagination using a grid view bound to an ObjectDataSource that is persistent in memory.

Topics Covered in this project:

  • Binding a GridView control to an ObjectDataSource.
  • Singleton Collections.
  • Using a GridView inside an Asp.net AJAX UpdatePanel.
  • Querying objects using Linq.
  • Using Skip() and Take() with Linq.
  • Custom Data Pagination.

Data Pagination

If you are unfamiliar with data pagination what you need to first need to understand is that out of the box you asp.net controls will paginate using UI pagination. Simply stated this means that all of the data is returned to your control and then filtered before the aspx renders the html to the client browser. This may be fine in some instances but generally this is bad for performance. Using a data pagination technique you will only return the data which will be displayed by your control. If you have already taken a look at the online demo for this project you already have seen how much better the performance of a data pagination technique is in comparison.

Background

This project is an example of using Linq to query a Singleton collection. This basically states that the collection persists in memory at the application level of your IIS process. This is achieved by using static or shared instances, or by using .net web.caching, or other third party cache mechanisms such as zcache or ncache. If you do not want to persist your data in memory then rownumber is the best way for you to achieve data pagination.

Using the code

The download zip file contains the Visual Studio 2008 project and source files necessary to run the online demo as well as a csv containing a zip code database and a stored procedure used to load the data and referenced inside the code. You will need to update the connection string located in the web.config file to point to your data source after you have imported the zip code data and ran the stored procedure script.

Points of Interest

Using Linq syntax to retrieve "sub-collections" from your collections is a great alternative to a classic approach. Using a classic approach you would most times need to create a second instance of an object, loop through the first object and copy each of its members into the new new object. In this project I simply use the methods below to return a sub collection:

c#
        /// <span class="code-SummaryComment"><summary /> </span>
        /// GetZipCodes 
        /// <span class="code-SummaryComment"></summary /> </span>
        /// <span class="code-SummaryComment"><param name="ResultsPerPage" /></param /> </span>
        /// <span class="code-SummaryComment"><param name="PageNumber" /></param /> </span>
        /// <span class="code-SummaryComment"><returns /> </span>
        /// IEnumerable(Of ZipCode) 
        /// <span class="code-SummaryComment"></returns /> </span>
        /// <span class="code-SummaryComment"><remarks /> </span>
        /// Page Clone of Instance Data Using Linq 
        /// <span class="code-SummaryComment"></remarks /> </span>
        public static IEnumerable<ZipCodeObjects.ZipCode> GetZipCodes(int ResultsPerPage, int PageNumber)
        {

            //number of records to skip 
            int skip = (PageNumber - 1) * ResultsPerPage;

            //number of results per page. 
            int take = ResultsPerPage;

            //execute Linq query for result set
            IEnumerable<zipcodeobjects.zipcode /> result = (from zipcodes in ZipCodeInstance select zipcodes).Skip(skip).Take(ResultsPerPage);

            //return result 
            return result;
        }
</zipcodeobjects.zipcode />

Vb.net
        ''' <span class="code-SummaryComment"><summary></span>
        ''' GetZipCodes
        ''' <span class="code-SummaryComment"></summary></span>
        ''' <span class="code-SummaryComment"><param name="ResultsPerPage"></param></span>
        ''' <span class="code-SummaryComment"><param name="PageNumber"></param></span>
        ''' <span class="code-SummaryComment"><returns></span>
        ''' IEnumerable(Of ZipCode)
        ''' <span class="code-SummaryComment"></returns></span>
        ''' <span class="code-SummaryComment"><remarks></span>
        ''' Page Clone of Instance Data Using Linq
        ''' <span class="code-SummaryComment"></remarks></span>
        Public Shared Function GetZipCodes(ByVal ResultsPerPage As Integer, _
                                           ByVal PageNumber As Integer) As IEnumerable(Of ZipCode)

            'number of records to skip
            Dim skip As Integer = (PageNumber - 1) * ResultsPerPage

            'number of results per page.
            Dim take As Integer = ResultsPerPage

            'execute query for result set
            Dim result As IEnumerable(Of ZipCode) = _
                (From zipcodes In ZipCodeInstance).Skip(skip).Take(take)

            'return result
            Return result
        End Function

Here is the complete class, the constructor is set to private in the collection to ensure only one single instance of the collection. Additionally the lock or sync lock is used to ensure thread safety.

The in memory instance of your collection is not paged or altered, altering this instance would alter the instance for all users. For this reason we return smaller copies of the object when requested by the user.

c#
using System;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Linq;
using System.Collections.Generic;


namespace ZipCodeObjects
{
    /// <span class="code-SummaryComment"><summary> </span>
    /// ZipCodeCollection 
    /// <span class="code-SummaryComment"></summary> </span>
    /// <span class="code-SummaryComment"><remarks> </span>
    /// Contains Collection of zip codes and meta. 
    /// <span class="code-SummaryComment"></remarks> </span>
    public class ZipCodeCollection
    {

        /// <span class="code-SummaryComment"><summary> </span>
        /// ReadLock 
        /// <span class="code-SummaryComment"></summary> </span>
        /// <span class="code-SummaryComment"><remarks> </span>
        /// Used By SyncLock to ensure Thread Safety 
        /// <span class="code-SummaryComment"></remarks> </span>
        private static readonly object ReadLock = new object();

        /// <span class="code-SummaryComment"><summary> </span>
        /// ZipCodeInstance 
        /// <span class="code-SummaryComment"></summary> </span>
        /// <span class="code-SummaryComment"><remarks> </span>
        /// ZipCodeInstance 
        /// Singleton Collection of Zip Codes and meta. 
        /// <span class="code-SummaryComment"></remarks> </span>
        private static List<ZipCode> m_ZipCodeInstance;
        public static List<ZipCode> ZipCodeInstance
        {
            get
            {
                // initialize if not already done 
                if (m_ZipCodeInstance == null)
                {

                    //only allow 1 person to load data at once. 
                    lock (ReadLock)
                    {
                        if (m_ZipCodeInstance == null)
                        {
                            m_ZipCodeInstance = LoadData();
                        }
                    }

                }
                return m_ZipCodeInstance;
            }
        }

        /// <span class="code-SummaryComment"><summary> </span>
        /// GetZipCodes 
        /// <span class="code-SummaryComment"></summary> </span>
        /// <span class="code-SummaryComment"><param name="ResultsPerPage"></param> </span>
        /// <span class="code-SummaryComment"><param name="PageNumber"></param> </span>
        /// <span class="code-SummaryComment"><returns> </span>
        /// IEnumerable(Of ZipCode) 
        /// <span class="code-SummaryComment"></returns> </span>
        /// <span class="code-SummaryComment"><remarks> </span>
        /// Page Clone of Instance Data Using Linq 
        /// <span class="code-SummaryComment"></remarks> </span>
        public static IEnumerable<ZipCodeObjects.ZipCode> GetZipCodes(int ResultsPerPage, int PageNumber)
        {

            //number of records to skip 
            int skip = (PageNumber - 1) * ResultsPerPage;

            //number of results per page. 
            int take = ResultsPerPage;

            //execute Linq query for result set
            IEnumerable<ZipCodeObjects.ZipCode> result = (from zipcodes in ZipCodeInstance select zipcodes).Skip(skip).Take(ResultsPerPage);

            //return result 
            return result;
        }

        /// <span class="code-SummaryComment"><summary> </span>
        /// SelectCount 
        /// <span class="code-SummaryComment"></summary> </span>
        /// <span class="code-SummaryComment"><returns> </span>
        /// Integer 
        /// <span class="code-SummaryComment"></returns> </span>
        /// <span class="code-SummaryComment"><remarks> </span>
        /// Returns total number of records in instance. 
        /// Uses Linq 
        /// <span class="code-SummaryComment"></remarks> </span>
        public static int SelectCount()
        {
            return (from zipcodes in ZipCodeInstance select zipcodes).Count();
        }

        /// <span class="code-SummaryComment"><summary> </span>
        /// LoadData 
        /// <span class="code-SummaryComment"></summary> </span>
        /// <span class="code-SummaryComment"><returns> </span>
        /// List(Of ZipCode) 
        /// <span class="code-SummaryComment"></returns> </span>
        /// <span class="code-SummaryComment"><remarks> </span>
        /// Load collection of zip codes from database. 
        /// <span class="code-SummaryComment"></remarks> </span>
        private static List<ZipCode> LoadData()
        {

            //create new instance of zip code collection 
            List<ZipCode> ziplist = new List<ZipCode>();

            //setup database connection 
            System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection();
            conn.ConnectionString = ConfigurationManager.ConnectionStrings["ProgrammersJournal"].ConnectionString;

            //open connection 
            conn.Open();

            try
            {

                //define sql command 
                SqlCommand cmd = new SqlCommand("pj_getallzipcodes", conn);

                //execute and loop through reader. 
                using (System.Data.SqlClient.SqlDataReader reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {

                        //add zip object to list. 
                        ziplist.Add(new ZipCode(reader.GetSqlString(0).ToString(), reader.GetSqlString(1).ToString(), reader.GetSqlString(2).ToString(), Convert.ToDecimal(reader.GetSqlString(3).ToString()), Convert.ToDecimal(reader.GetSqlString(4).ToString()), Convert.ToInt32(reader.GetSqlString(5).ToString()), Convert.ToInt16(reader.GetSqlString(6).ToString())));
                    }
                }
            }

            catch (Exception ex)
            {

                //bubble exception 
                throw new Exception(ex.Message);
            }

            finally
            {

                //close connection 
                if (conn.State != ConnectionState.Closed)
                {
                    conn.Close();
                }

                //instance is populated 
                //force garbage collection 
                GC.Collect();
                GC.WaitForPendingFinalizers();

            }

            //return new instance of zip code collection 
            return ziplist;
        }

        /// <span class="code-SummaryComment"><summary> </span>
        /// New 
        /// <span class="code-SummaryComment"></summary> </span>
        /// <span class="code-SummaryComment"><remarks> </span>
        /// Conrtructor set to private to ensure 
        /// instances of the obect cannot be created 
        /// outside of this class. 
        /// <span class="code-SummaryComment"></remarks> </span>
        private ZipCodeCollection()
        {

        }

    } 

    /// <span class="code-SummaryComment"><summary> </span>
    /// ZipCode 
    /// <span class="code-SummaryComment"></summary> </span>
    /// <span class="code-SummaryComment"><remarks> </span>
    /// Single Zip code record and associated meta. 
    /// <span class="code-SummaryComment"></remarks> </span>
    public class ZipCode
    {

        /// <span class="code-SummaryComment"><summary> </span>
        /// Zip 
        /// <span class="code-SummaryComment"></summary> </span>
        /// <span class="code-SummaryComment"><remarks> </span>
        /// Zip Code 
        /// <span class="code-SummaryComment"></remarks> </span>
        private string m_Zip;
        public string Zip
        {
            get { return m_Zip; }
        }

        /// <span class="code-SummaryComment"><summary> </span>
        /// City 
        /// <span class="code-SummaryComment"></summary> </span>
        /// <span class="code-SummaryComment"><remarks> </span>
        /// City where zip code is located. 
        /// <span class="code-SummaryComment"></remarks> </span>
        private string m_City;
        public string City
        {
            get { return m_City; }
        }

        /// <span class="code-SummaryComment"><summary> </span>
        /// State 
        /// <span class="code-SummaryComment"></summary> </span>
        /// <span class="code-SummaryComment"><remarks> </span>
        /// State where zip code is located. 
        /// <span class="code-SummaryComment"></remarks> </span>
        private string m_State;
        public string State
        {
            get { return m_State; }
        }

        /// <span class="code-SummaryComment"><summary> </span>
        /// Latitude 
        /// <span class="code-SummaryComment"></summary> </span>
        /// <span class="code-SummaryComment"><remarks> </span>
        /// Latitude reference for this zip code. 
        /// <span class="code-SummaryComment"></remarks> </span>
        private decimal m_Latitude;
        public decimal Latitude
        {
            get { return m_Latitude; }
        }

        /// <span class="code-SummaryComment"><summary> </span>
        /// Longitude 
        /// <span class="code-SummaryComment"></summary> </span>
        /// <span class="code-SummaryComment"><remarks> </span>
        /// Longitude reference for this zip code. 
        /// <span class="code-SummaryComment"></remarks> </span>
        private decimal m_Longitude;
        public decimal Longitude
        {
            get { return m_Longitude; }
        }

        /// <span class="code-SummaryComment"><summary> </span>
        /// TimeZone 
        /// <span class="code-SummaryComment"></summary> </span>
        /// <span class="code-SummaryComment"><remarks> </span>
        /// TimeZone reference for this zip code. 
        /// <span class="code-SummaryComment"></remarks> </span>
        private int m_TimeZone;
        public int TimeZone
        {
            get { return m_TimeZone; }
        }

        /// <span class="code-SummaryComment"><summary> </span>
        /// Dst 
        /// <span class="code-SummaryComment"></summary> </span>
        /// <span class="code-SummaryComment"><remarks> </span>
        /// Dst reference for this zip code. 
        /// <span class="code-SummaryComment"></remarks> </span>
        private short m_Dst;
        public short Dst
        {
            get { return m_Dst; }
        }

        /// <span class="code-SummaryComment"><summary> </span>
        /// New 
        /// <span class="code-SummaryComment"></summary> </span>
        /// <span class="code-SummaryComment"><remarks> </span>
        /// parameterless constructor 
        /// <span class="code-SummaryComment"></remarks> </span>
        public ZipCode()
        {

        }

        /// <span class="code-SummaryComment"><summary> </span>
        /// New 
        /// <span class="code-SummaryComment"></summary> </span>
        /// <span class="code-SummaryComment"><param name="zip"></param> </span>
        /// <span class="code-SummaryComment"><param name="city"></param> </span>
        /// <span class="code-SummaryComment"><param name="state"></param> </span>
        /// <span class="code-SummaryComment"><param name="latitude"></param> </span>
        /// <span class="code-SummaryComment"><param name="longitude"></param> </span>
        /// <span class="code-SummaryComment"><param name="timeZone"></param> </span>
        /// <span class="code-SummaryComment"><param name="dst"></param> </span>
        /// <span class="code-SummaryComment"><remarks> </span>
        /// Custom Contructor 
        /// <span class="code-SummaryComment"></remarks> </span>
        public ZipCode(string zip, string city, string state, decimal latitude, decimal longitude, int timeZone, short dst)
        {

            this.m_Zip = zip;
            this.m_City = city;
            this.m_State = state;
            this.m_Latitude = latitude;
            this.m_Longitude = longitude;
            this.m_TimeZone = timeZone;
            this.m_Dst = dst;

        }

    } 
}

Vb.net
 
Imports System.Data
Imports System.Data.SqlClient
Imports System.Configuration
Imports System.Linq

Namespace ZipCodeObjects

    ''' <span class="code-SummaryComment"><summary></span>
    ''' ZipCodeCollection
    ''' <span class="code-SummaryComment"></summary></span>
    ''' <span class="code-SummaryComment"><remarks></span>
    ''' Contains Collection of zip codes and meta.
    ''' <span class="code-SummaryComment"></remarks></span>
    Public Class ZipCodeCollection

        ''' <span class="code-SummaryComment"><summary></span>
        ''' ReadLock
        ''' <span class="code-SummaryComment"></summary></span>
        ''' <span class="code-SummaryComment"><remarks></span>
        ''' Used By SyncLock to ensure Thread Safety
        ''' <span class="code-SummaryComment"></remarks></span>
        Private Shared ReadOnly ReadLock As New Object()

        ''' <span class="code-SummaryComment"><summary></span>
        ''' ZipCodeInstance
        ''' <span class="code-SummaryComment"></summary></span>
        ''' <span class="code-SummaryComment"><remarks></span>
        ''' ZipCodeInstance
        ''' Singleton Collection of Zip Codes and meta.
        ''' <span class="code-SummaryComment"></remarks></span>
        Private Shared m_ZipCodeInstance As List(Of ZipCode)
        Public Shared ReadOnly Property ZipCodeInstance() As List(Of ZipCode)
            Get
                ' initialize if not already done
                If m_ZipCodeInstance Is Nothing Then

                    'only allow 1 person to load data at once.
                    SyncLock ReadLock
                        If m_ZipCodeInstance Is Nothing Then
                            m_ZipCodeInstance = LoadData()
                        End If
                    End SyncLock

                End If
                Return m_ZipCodeInstance
            End Get
        End Property

        ''' <span class="code-SummaryComment"><summary></span>
        ''' GetZipCodes
        ''' <span class="code-SummaryComment"></summary></span>
        ''' <span class="code-SummaryComment"><param name="ResultsPerPage"></param></span>
        ''' <span class="code-SummaryComment"><param name="PageNumber"></param></span>
        ''' <span class="code-SummaryComment"><returns></span>
        ''' IEnumerable(Of ZipCode)
        ''' <span class="code-SummaryComment"></returns></span>
        ''' <span class="code-SummaryComment"><remarks></span>
        ''' Page Clone of Instance Data Using Linq
        ''' <span class="code-SummaryComment"></remarks></span>
        Public Shared Function GetZipCodes(ByVal ResultsPerPage As Integer, _
                                           ByVal PageNumber As Integer) As IEnumerable(Of ZipCode)

            'number of records to skip
            Dim skip As Integer = (PageNumber - 1) * ResultsPerPage

            'number of results per page.
            Dim take As Integer = ResultsPerPage

            'execute query for result set
            Dim result As IEnumerable(Of ZipCode) = _
                (From zipcodes In ZipCodeInstance).Skip(skip).Take(take)

            'return result
            Return result
        End Function

        ''' <span class="code-SummaryComment"><summary></span>
        ''' SelectCount
        ''' <span class="code-SummaryComment"></summary></span>
        ''' <span class="code-SummaryComment"><returns></span>
        ''' Integer
        ''' <span class="code-SummaryComment"></returns></span>
        ''' <span class="code-SummaryComment"><remarks></span>
        ''' Returns total number of records in instance.
        ''' Uses Linq
        ''' <span class="code-SummaryComment"></remarks></span>
        Public Shared Function SelectCount() As Integer
            Return (From zipcodes In ZipCodeInstance).Count()
        End Function

        ''' <span class="code-SummaryComment"><summary></span>
        ''' LoadData
        ''' <span class="code-SummaryComment"></summary></span>
        ''' <span class="code-SummaryComment"><returns></span>
        ''' List(Of ZipCode)
        ''' <span class="code-SummaryComment"></returns></span>
        ''' <span class="code-SummaryComment"><remarks></span>
        ''' Load collection of zip codes from database.
        ''' <span class="code-SummaryComment"></remarks></span>
        Private Shared Function LoadData() As List(Of ZipCode)

            'create new instance of zip code collection
            Dim ziplist As New List(Of ZipCode)

            'setup database connection
            Dim conn As New System.Data.SqlClient.SqlConnection()
            conn.ConnectionString = ConfigurationManager.ConnectionStrings("ProgrammersJournal").ConnectionString

            'open connection
            conn.Open()

            Try

                'define sql command
                Dim cmd As New SqlCommand("pj_getallzipcodes", conn)

                'execute and loop through reader.
                Using reader As SqlClient.SqlDataReader = cmd.ExecuteReader()
                    While reader.Read()

                        'add zip object to list.
                        ziplist.Add(New ZipCode(reader.GetSqlString(0).ToString(), _
                                                reader.GetSqlString(1).ToString(), _
                                                reader.GetSqlString(2).ToString(), _
                                                Convert.ToDecimal(reader.GetSqlString(3).ToString()), _
                                                Convert.ToDecimal(reader.GetSqlString(4).ToString()), _
                                                Convert.ToInt32(reader.GetSqlString(5).ToString()), _
                                                Convert.ToInt16(reader.GetSqlString(6).ToString())))
                    End While
                End Using

            Catch ex As Exception

                'bubble exception
                Throw New Exception(ex.Message)

            Finally

                'close connection
                If conn.State <> ConnectionState.Closed Then
                    conn.Close()
                End If

                'instance is populated
                'force garbage collection
                GC.Collect()
                GC.WaitForPendingFinalizers()

            End Try

            'return new instance of zip code collection
            Return ziplist
        End Function

        ''' <span class="code-SummaryComment"><summary></span>
        ''' New
        ''' <span class="code-SummaryComment"></summary></span>
        ''' <span class="code-SummaryComment"><remarks></span>
        ''' Conrtructor set to private to ensure 
        ''' instances of the obect cannot be created
        ''' outside of this class.
        ''' <span class="code-SummaryComment"></remarks></span>
        Private Sub New()

        End Sub

    End Class

    ''' <span class="code-SummaryComment"><summary></span>
    ''' ZipCode
    ''' <span class="code-SummaryComment"></summary></span>
    ''' <span class="code-SummaryComment"><remarks></span>
    ''' Single Zip code record and associated meta.
    ''' <span class="code-SummaryComment"></remarks></span>
    Public Class ZipCode

        ''' <span class="code-SummaryComment"><summary></span>
        ''' Zip
        ''' <span class="code-SummaryComment"></summary></span>
        ''' <span class="code-SummaryComment"><remarks></span>
        ''' Zip Code
        ''' <span class="code-SummaryComment"></remarks></span>
        Private m_Zip As String
        Public ReadOnly Property Zip() As String
            Get
                Return m_Zip
            End Get
        End Property

        ''' <span class="code-SummaryComment"><summary></span>
        ''' City
        ''' <span class="code-SummaryComment"></summary></span>
        ''' <span class="code-SummaryComment"><remarks></span>
        ''' City where zip code is located.
        ''' <span class="code-SummaryComment"></remarks></span>
        Private m_City As String
        Public ReadOnly Property City() As String
            Get
                Return m_City
            End Get
        End Property

        ''' <span class="code-SummaryComment"><summary></span>
        ''' State
        ''' <span class="code-SummaryComment"></summary></span>
        ''' <span class="code-SummaryComment"><remarks></span>
        ''' State where zip code is located.
        ''' <span class="code-SummaryComment"></remarks></span>
        Private m_State As String
        Public ReadOnly Property State() As String
            Get
                Return m_State
            End Get
        End Property

        ''' <span class="code-SummaryComment"><summary></span>
        ''' Latitude
        ''' <span class="code-SummaryComment"></summary></span>
        ''' <span class="code-SummaryComment"><remarks></span>
        ''' Latitude reference for this zip code.
        ''' <span class="code-SummaryComment"></remarks></span>
        Private m_Latitude As Decimal
        Public ReadOnly Property Latitude() As Decimal
            Get
                Return m_Latitude
            End Get
        End Property

        ''' <span class="code-SummaryComment"><summary></span>
        ''' Longitude
        ''' <span class="code-SummaryComment"></summary></span>
        ''' <span class="code-SummaryComment"><remarks></span>
        ''' Longitude reference for this zip code.
        ''' <span class="code-SummaryComment"></remarks></span>
        Private m_Longitude As Decimal
        Public ReadOnly Property Longitude() As Decimal
            Get
                Return m_Longitude
            End Get
        End Property

        ''' <span class="code-SummaryComment"><summary></span>
        ''' TimeZone
        ''' <span class="code-SummaryComment"></summary></span>
        ''' <span class="code-SummaryComment"><remarks></span>
        ''' TimeZone reference for this zip code.
        ''' <span class="code-SummaryComment"></remarks></span>
        Private m_TimeZone As Integer
        Public ReadOnly Property TimeZone() As Integer
            Get
                Return m_TimeZone
            End Get
        End Property

        ''' <span class="code-SummaryComment"><summary></span>
        ''' Dst
        ''' <span class="code-SummaryComment"></summary></span>
        ''' <span class="code-SummaryComment"><remarks></span>
        ''' Dst reference for this zip code.
        ''' <span class="code-SummaryComment"></remarks></span>
        Private m_Dst As Short
        Public ReadOnly Property Dst() As Short
            Get
                Return m_Dst
            End Get
        End Property

        ''' <span class="code-SummaryComment"><summary></span>
        ''' New
        ''' <span class="code-SummaryComment"></summary></span>
        ''' <span class="code-SummaryComment"><remarks></span>
        ''' parameterless constructor
        ''' <span class="code-SummaryComment"></remarks></span>
        Public Sub New()

        End Sub

        ''' <span class="code-SummaryComment"><summary></span>
        ''' New
        ''' <span class="code-SummaryComment"></summary></span>
        ''' <span class="code-SummaryComment"><param name="zip"></param></span>
        ''' <span class="code-SummaryComment"><param name="city"></param></span>
        ''' <span class="code-SummaryComment"><param name="state"></param></span>
        ''' <span class="code-SummaryComment"><param name="latitude"></param></span>
        ''' <span class="code-SummaryComment"><param name="longitude"></param></span>
        ''' <span class="code-SummaryComment"><param name="timeZone"></param></span>
        ''' <span class="code-SummaryComment"><param name="dst"></param></span>
        ''' <span class="code-SummaryComment"><remarks></span>
        ''' Custom Contructor
        ''' <span class="code-SummaryComment"></remarks></span>
        Public Sub New(ByVal zip As String, _
                       ByVal city As String, _
                       ByVal state As String, _
                       ByVal latitude As Decimal, _
                       ByVal longitude As Decimal, _
                       ByVal timeZone As Integer, _
                       ByVal dst As Short)

            Me.m_Zip = zip
            Me.m_City = city
            Me.m_State = state
            Me.m_Latitude = latitude
            Me.m_Longitude = longitude
            Me.m_TimeZone = timeZone
            Me.m_Dst = dst

        End Sub

    End Class

End Namespace

Binding your GridView to your collection is very easily done using an ObjectDataSource.

<asp:ObjectDataSource ID="ZipCodeObjectDataSource" runat="server" SelectMethod="GetZipCodes"
    TypeName="ZipCodeObjects.ZipCodeCollection">
    <SelectParameters>
    <asp:SessionParameter DefaultValue="20" Name="ResultsPerPage" SessionField="ResultsPerPage"
        Type="Int32" />
    <asp:SessionParameter DefaultValue="1" Name="PageNumber" SessionField="PageNumber"
        Type="Int32" />
    </SelectParameters>
</asp:ObjectDataSource>

From here all that is left is a simple paging mechanism and UI. Download the demo project for the complete source code and database.

History

  • 3/19/2008: Posted Code Samples And Article
  • 3/19/2008: Uploaded Sample Projects
  • 3/20/2008: Copy Only Edit.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Jason Witty
Software Developer (Senior)
United States United States
For more articles please visit my website:
http://www.aprogrammersjournal.com
 
A Programmers Journal
RSS

Comments and Discussions

 
QuestionSolves problem but.. PinmemberYasir-mx11-Feb-13 4:07 
GeneralMy vote of 3 PinmemberYasir-mx10-Feb-13 23:03 
GeneralGreat! PinmemberAnt210027-Aug-09 0:23 
GeneralGood article Pinmemberredfred6-Oct-08 21:42 
However, when I run the VB code I get the following error:-
 
String input not in correct format.
 
would welcome advice.
 
Regards
 
Jim
 
jim.jack@fleet-support.co.uk
GeneralRe: Good article PinmemberJason Witty7-Oct-08 5:28 
GeneralThanks PinmemberUnRusoDeCaracas19-Mar-08 6:42 
GeneralExcellent Pinmembermerlin98119-Mar-08 5:44 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140721.1 | Last Updated 19 Mar 2008
Article Copyright 2008 by Jason Witty
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid