Archive

Archive for October, 2010

Sorting with custom lambda expressions

October 12th, 2010 No comments

When working with dynamic sorting e.g. when using a GridView/ObjectDataSource combination which will sort according to the column header clicked, the most intuitive way of realizing sorting behavoiur in the ObjectDataSource is by using a large if/switch construct.

A smarter way is to use custom lambda expressions with Linq, which will automatically construct the correct Linq query according to the column name and sort order. No matter how many columns, whether sorted ascending or descending, the following code will handle it all:

/// <summary>This Linq helper class constructs a custom lambda expression used for sorting.</summary>
public static class LinqExtensions
{
    /// <summary>Generic method used for sorting according to the pseudo SQL syntax emmitted by ObjectDataSource.</summary>
    public static IQueryable<T> OrderBySQLSyntax<T>( this IQueryable<T> source, string sPropertyParameter )
    {
        string[] asParams = sPropertyParameter.Split( new char[] { ' ' }, 2 );
        bool descending = ( asParams.Length == 2 && String.Equals( asParams[ 1 ], "DESC" ) );
        return (IQueryable<T>)OrderByExtension( source, asParams[ 0 ], descending );
    }
 
    /// <summary>Used for sorting in ascending/descending order according to the property provided.</summary>
    public static IQueryable OrderByExtension( this IQueryable source, string propertyName, bool descending )
    {
        var x = Expression.Parameter( source.ElementType, "x" );
        var selector = Expression.Lambda( Expression.PropertyOrField( x, propertyName ), x );
        MethodCallExpression mce = Expression.Call( typeof( Queryable ), descending ? "OrderByDescending" : "OrderBy",
            new Type[] { source.ElementType, selector.Body.Type }, source.Expression, selector );
        return source.Provider.CreateQuery( mce );
    }
}