Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Generic sorting of customer objects for ObjectDataSource (ASP.NET)

0.00/5 (No votes)
23 Oct 2008 1  
Generic sorting of customer objects for ObjectDataSource in ASP.NET.

Introduction

The class PropertyComparer provides the possibility for data-access-components to enable sorting for customer objects when using an ObjectDataSource.

Background

ASP.NET 2.0 includes the controls GridView and ObjectDataSource. You can define which methods of your data-access-component is used by the ObjectDataSource. If the Select method returns a DataSet or a DataTable, you can use paging and sorting for the GridView out of the box.

If you want to work with collections of business-objects instead of DataSet/DataTable, you have to implement the sorting yourself. I wrote a generic comparer for use with all my business-objects.

Using the code

Use a GridView where you define the DataSourceId, and enable sorting:

<asp:GridView     ID="exampleGridView" runat="server" 
        DataSourceID="exampleDataSource" 
        AllowSorting="True" ... >

Define the ObjectDataSource:

<asp:ObjectDataSource     ID="exampleDataSource" runat="server" 
            TypeName="ExampleDataAccessComponent" 
            SelectMethod="Select" 
            SortParameterName="orderBy" ... >

Write your data-access-component implementing the Select method:

[DataObject()]
public sealed class ActivityDac
{
    private string myConnectionString;
    private DbProviderFactory myFactory;


    public ActivityDac()
    {
        ConnectionStringSettings cs = 
           ConfigurationManager.ConnectionStrings[" ... "];
        myFactory = DbProviderFactories.GetFactory(cs.ProviderName);
        myConnectionString = cs.ConnectionString;
    }


    [DataObjectMethod(DataObjectMethodType.Select, true)]
    public Activity[] Select(string orderBy)
    {
        List<BusinessClass> list = new List<BusinessClass>();
        using (DbConnection con = myFactory.CreateConnection())
        {
            con.ConnectionString = myConnectionString;
            using (DbCommand cmd = myFactory.CreateCommand())
            {
                cmd.Connection = con;
                cmd.CommandText = " ... ";

                DbParameter p = myFactory.CreateParameter();
                ...
                cmd.Parameters.Add(p);

                con.Open();
                DbDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleResult);

                while (reader.Read())
                {
                    BusinessClass o = new BusinessClass(reader.GetInt32(0));
                    ..
                    list.Add(o);
                }
            }
        }

        if (!String.IsNullOrEmpty(orderBy))
        {
            PropertyComparer<BusinessClass> comparer = 
              new PropertyComparer<BusinessClass>(orderBy);
            list.Sort(comparer);
        }

        return list.ToArray();
    }
}

Here is the code for the PropertyComparer:

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Collections;

namespace Example
{
    public class PropertyComparer<T> : IComparer<T>
    {
        private enum SortType
        {
            Descending = -1,
            Ascending = 1
        }


        private SortType mySortDirecton;
        private string mySortPropertyName;


        public PropertyComparer(string sortString)
        {
            if (sortString == null)
                throw new ArgumentNullException("sortString");
            if (sortString.Length == 0)
                throw new ArgumentOutOfRangeException("sortString");

            if (sortString.ToLower().EndsWith(" desc"))
            {
                mySortPropertyName = sortString.Substring(0, sortString.Length - 5);
                mySortDirecton = SortType.Descending;
            }
            else
            {
                if (sortString.ToLower().EndsWith(" asc"))
                    mySortPropertyName = sortString.Substring(0, sortString.Length - 4);
                else
                    this.mySortPropertyName = sortString;

                this.mySortDirecton = SortType.Ascending;
            }
        }


        #region IComparer<T> Members

        public int Compare(T x, T y)
        {
            if ((x == null) && (y == null))
                return 0;
            if (x == null)
                return -(int)mySortDirecton;
            if (y == null)
                return (int)mySortDirecton;

            PropertyInfo p = x.GetType().GetProperty(mySortPropertyName);
            if (p == null)
                throw new ApplicationException();

            object vX = p.GetValue(x, null);
            object vY = p.GetValue(y, null);

            if ((vX == null) && (vY == null))
                return 0;
            if (vX == null)
                return -(int)mySortDirecton;
            if (vY == null)
                return (int)mySortDirecton;

            return (int)mySortDirecton * Comparer.DefaultInvariant.Compare(vX, vY);
        }

        #endregion
    }
}

History

  • Oct. 24, 2008: 9:23 - Corrected typo.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here