Dynamic Sorting with Linq

When trying to implement a Business Logic Layer (i will refer to this as BLL) with linq one thing that is an annoyance is sorting. Lets say you had a BLL that was being used by ObjectDataSource and had a select method that does sorting and paging, then you'd probably be tempted to write something like this:

private IQueryable<Product> SortBy(IQueryable<Product> source, string sortBy) {

    int desc = sortBy.IndexOf("DESC");

    bool isDescending = desc >= 0;

    if (isDescending) {

        sortBy = sortBy.Substring(0, desc).Trim();

    }

    switch (sortBy) {

        case "ProductName":

            if (isDescending) {

                return source.OrderByDescending(p => p.ProductName);

            }

            source = source.OrderBy(p => p.ProductName);

            break;

        case "UnitPrice":

            if (isDescending) {

                return source.OrderByDescending(p => p.UnitPrice);

            }

            source = source.OrderBy(p => p.UnitPrice);

            break;

..... One for every property

    }

    return source;

}

But that can be really tedious and you probably have more than one object. Would you want to duplicate that for Categories, Suppliers, etc? I don't think so. Linq takes
advantage of another C# 3.0 feature called Expression Trees and we can take advantage of these in our code to build a dynamic sort expression for any object.

The code:
So how do we do this? I'm not going to explain how expression trees work in this blog post but there are plenty of resources out there  that you can take a look at if your interested.
The method is an extension method on IQueryable<T> that takes the IQuerable<T> source and the sort parameter which should be the property name that you would like to sort by. In the case of DataSources like ObjectDataSource, the sort parameter will contain "DESC' if the sort direction is descending. Here is the code:

public static class QueryExtensions {

    public static IQueryable<T> SortBy<T>(this IQueryable<T> source, string propertyName) {

        if (source == null) {

            throw new ArgumentNullException("source");

        }

        // DataSource control passes the sort parameter with a direction

        // if the direction is descending          

        int descIndex = propertyName.IndexOf(" DESC");

        if (descIndex >= 0) {

            propertyName = propertyName.Substring(0, descIndex).Trim();

        }

 

        if (String.IsNullOrEmpty(propertyName)) {

            return source;

        }

 

        ParameterExpression parameter = Expression.Parameter(source.ElementType, String.Empty);

        MemberExpression property = Expression.Property(parameter, propertyName);

        LambdaExpression lambda = Expression.Lambda(property, parameter);

 

        string methodName = (descIndex < 0) ? "OrderBy" : "OrderByDescending";

 

        Expression methodCallExpression = Expression.Call(typeof(Queryable), methodName,

                                            new Type[] { source.ElementType, property.Type },

                                            source.Expression, Expression.Quote(lambda));

 

        return source.Provider.CreateQuery<T>(methodCallExpression);

    }

}

And a link to the file.

QueryExtensions.cs

Hope this helps

Published Thursday, December 11, 2008 5:26 AM by davidfowl
Filed under: , ,

Comments

# re: Dynamic Sorting with Linq

Thursday, December 11, 2008 9:26 AM by Sébastien Ros

... or you can simply use the LINQ Dynamic Query Library provided by Microsoft. See the post from Scott Guthrie: weblogs.asp.net/.../dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

# re: Dynamic Sorting with Linq

Thursday, December 11, 2008 9:43 AM by davidfowl

Ah yes that is a much more heavy weight solution, but you are right about that :).

# Reflective Perspective - Chris Alcock &raquo; The Morning Brew #243

Pingback from  Reflective Perspective - Chris Alcock  &raquo; The Morning Brew #243

# re: Dynamic Sorting with Linq

Friday, January 02, 2009 3:32 PM by Fahad

Can you do a dynamic Grouping + a select to get the IGrouping<T,K> values?

# re: Dynamic Sorting with Linq

Friday, January 09, 2009 12:06 PM by Ben Dewey

I'm using this and its great.  I found an issue I was getting a bug when sorting by my field called Description (DESCription).  I changed the code to search for the IndexOf(" DESC") with the space first and all good.

# re: Dynamic Sorting with Linq

Wednesday, January 14, 2009 4:31 PM by davidfowl

Thanks for finding that bug, I'll patch the code.

# Dynamic Data FAQ

Wednesday, February 18, 2009 2:38 PM by Ricka on Dynamic Data

Please post corrections/new submissions to the Dynamic Data Forum . Put FAQ Submission/Correction in

# re: Dynamic Sorting with Linq

Thursday, March 12, 2009 10:08 AM by Brad

Ok, so how would I implement this "QueryExtensions" into my current BLL??

# re: Dynamic Sorting with Linq

Tuesday, April 21, 2009 8:08 AM by Abhishek Arora

A very nice blog.. and it solved my problem..

thanks david

# re: Dynamic Sorting with Linq

Monday, April 27, 2009 10:18 AM by Mark Luca

Hi, i have following problem:

Class Department with fields:

string DepartmentName

Employee Manager ....

sorting by DepartmentName - no problem

but now I want to sort of Department by Manager.Name

Is it possible?

thanks

Mark

# Blog For .NET &raquo; Dynamic Sorting and Filtering with Linq To SQL

Thursday, September 03, 2009 10:23 PM by Blog For .NET » Dynamic Sorting and Filtering with Linq To SQL

Pingback from  Blog For .NET &raquo; Dynamic Sorting and Filtering with Linq To SQL

# Dynamic LINQ Part 2 (Evolution)

Thursday, August 19, 2010 4:34 AM by Unhandled Exception

A while ago, Scott Gu blogged about a Dynamic LINQ library that was part of the C# samples in VS2008

# re: Dynamic Sorting with Linq

Sunday, March 27, 2011 11:47 PM by weblogs.asp.net

Dynamic sorting with linq.. Dandy :)

# re: Dynamic Sorting with Linq

Friday, November 18, 2011 12:43 PM by Jonny B

Fantastic! Worked out of the box and helped me learn something new.

# re: Dynamic Sorting with Linq

Wednesday, February 08, 2012 5:08 PM by Joseph Schrag

Exactly what I was looking for & lightweight too.  Thanks!

# Anonymous Type LINQ Result and GridView Sorting in ASP.NET | TechBrij

Pingback from  Anonymous Type LINQ Result and GridView Sorting in ASP.NET | TechBrij

# Linq???????????????????????? | EvilCode ????????????

Friday, November 09, 2012 6:23 PM by Linq???????????????????????? | EvilCode ????????????

Pingback from  Linq???????????????????????? | EvilCode ????????????

Leave a Comment

(required) 
(required) 
(optional)
(required)