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.