Sorting and ordering Linq results with string field names


Hi,

Today at  work, I had to bind a GridView control to a stored procedure through a LinqDataSource. To do this, I used LinqDataSource’s Selecting event. For example :

protected void LinqDataSource1_Selecting(object sender, LinqDataSourceSelectEventArgs e)

{  e.Result = CustomersBiz.GetAll(); }

If we bind a grid to a store procedure, the grid and LinqDataSource won’t support sorting automatically. Therefore, to enable sorting we have to set the SortExpression of each grid column to a field name of GetAll() result.

Inside Selecting event handler, e.Arguments.SortExpression will expose the SortExpression value of the column that is going to be sorted. So we have a string field name but OrderBy extension method accepts a Func<TSource, TKey> expression to perform sorting.

For sorting this problem out, I made an expression using the field name in the following way:

First, I made a parameter to use it for creating an expression. The parameter is created with Expression.Parameter that takes two arguments. The first one is the type of the entity and the sencond one is just a name:

var param = Expression.Parameter(typeof(T), “item”);

Afterwards we create a LamdaExpression by using Expression.Property method:

var sortExpression = Expression.Lambda<Func<T, object>>Expression.Property(param, SortExpression);

Up to know everything is fine unless T is a value type. If we try to sort the Linq result based on a struct, like DateTime, we will get a runtime error. Therefore we have to box it to a reference type:

var sortExpression = Expression.Lambda<Func<T, object>>
(Expression.Convert(Expression.Property(param, SortExpression), typeof(object)), param);

Now everything is ready to sort the Linq result, or better say an IEnumerable object.

e.Result = CustomersBiz.GetAll().OrderBy(sortExpression);

With a reason that I really could not figure out what is it, the above expression raises a compile error saying that C# compiler can not infere the type of the type argument, whilst it shoud !

To overcome this problem I converted the result of Getall() method to IQueryable with AsQueryable extension method :

e.Result = CustomersBiz.GetAll().AsQueryable().OrderBy(sortExpression);

To make this code reuseable I wrote a helper class called LinqHelper with a static method named Sort to order any IEnumerable<T> object. This method supports both ascending and descending sortings:

public static IEnumerable<T> Sort(IEnumerable<T> source, string SortExpression)
{
bool SortDescending = false;
if (SortExpression.Contains(“DESC”))
{
SortDescending = true;
SortExpression = SortExpression.Replace(“DESC”, “”).Trim();
}

var param = Expression.Parameter(typeof(T), “item”);

var sortExpression = Expression.Lambda<Func<T, object>>
(Expression.Convert(Expression.Property(param, SortExpression), typeof(object)), param);

if (!SortDescending)
return source.AsQueryable<T>().OrderBy<T, object>(sortExpression);
else
return source.AsQueryable<T>().OrderByDescending<T, object>(sortExpression);
}

A similar method, with some more effort, can be used for filtering too with exploiting Where extension method.

Hope this article can be helpful 🙂

Advertisements

6 thoughts on “Sorting and ordering Linq results with string field names

  1. Hi,
    i follow you by your blog feed,
    that’s why i’m not commenting !!
    and about this post, i’m sure this will help me on my current project. so thank you for this useful article.

    i hope you continue your blogging…
    and sorry for my bad english too 🙂

  2. Remi Despres-Smyth says:

    Thanks for a great article! Seems to me this problem should be reasonably common, but it is not easy to find the solution on MSDN.

  3. Jonathan says:

    Really helpful, thanks so much. Linq is new to me, although i’ve been programming for 10+ years. A bit of a mind shift….

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s