Have you ever found yourself writing this code?

switch (columnName)
{
    case "Name":
        return objList.OrderBy(o => o.Name);

    case "Address":
        return objList.OrderBy(o => o.Address);

    ... etc ...
}

If so then you have probably wished you could do this:

    return objList.OrderBy(columnName);

However, that's not going to work because the LINQ method is looking for an expression tree rather than a column name. There are a few libraries out there such as the Dynamic LINQ Library, but if that feels a little heavyweight for you then the following solution may help.

This class is a generic sorter for collections of type T. There are two basic usage scenarios that are covered by its two sort methods. The first scenario is as above where you want to specify a column upon an object in a collection.
You would call the class using:

var prm = Expression.Parameter(typeof(MyObject), "root");
IList<MyObject> sortedList = new Sorter<MyObject>().Sort(list, prm, "Name", SortDirection.Ascending);

However, what if your object hierarchy was a little deeper than that. Consider the following:
    return objList.OrderBy(o => o.Details.Name);

The column is actually a property of an embedded object. This is the scenario that the second method handles. Because the actual sort column is an embedded object, we need to build an expression manually that describes the "path" to that property. The code is very similar to that of the first example, except in this case we are providing a MemberExpression instead of the string sortExpression.
var prm = Expression.Parameter(typeof(MyObject), "root");
MemberExpression keySelectExpr =
    Expression.Property(Expression.Property(prm, "Details"), "Name");
IList<MyObject> sortedList = new Sorter<MyObject>().Sort(list, prm, keySelectExpr, SortDirection.Ascending);


Source Code
The following is the code for the generic sorter class:

/// <summary>
/// A generic sorter class used to wrap the LINQ OrderBy functions.
/// </summary>
/// <typeparam name="T">The <see cref="System.Type"/> of object being sorted.</typeparam>
public class Sorter<T>
{
    /// <summary>
    /// Sorts a list of type T.
    /// </summary>
    /// <param name="list">The list to sort.</param>
    /// <param name="prmExpression">The expression defining the parameter to supply to the lambda expression.</param>
    /// <param name="sortExpression">The name of the property on the parameter object to sort by.
    /// <param name="sortDirection">The direction in which to sort the objects.</param>
    /// <returns>The sorted list.</returns>
    public List<T> Sort(
        IEnumerable<T> list,
        ParameterExpression prmExpression,
        string sortExpression,
        SortDirection sortDirection) {
        var lambda = Expression.Lambda<Func<T, object>>(Expression.Convert(Expression.Property(prmExpression, sortExpression), typeof(object)), prmExpression);
        return sortDirection == SortDirection.Ascending ?
            list.AsQueryable<T>().OrderBy<T, object>(lambda).ToList() :
            list.AsQueryable<T>().OrderByDescending<T, object>(lambda).ToList();
    }

    /// <summary>
    /// Sorts a list of type T.
    /// </summary>
    /// <param name="list">The list to sort.</param>
    /// <param name="prmExpression">The expression defining the parameter to supply to the lambda expression.</param>
    /// <param name="keySelectionExpression">
    /// A <see cref="MemberExpression"/> that identifies a property on an object in the supplied <param name="list"/> that is used to
    /// perform the sort.
    /// </param>
    /// <param name="sortDirection">The direction in which to sort the objects.</param>
    /// <returns>The sorted list.</returns>
    public List<T> Sort(
        IEnumerable<T> list,
        ParameterExpression prmExpression,
        MemberExpression sortExpression,
        SortDirection sortDirection) {
        var lambda = Expression.Lambda<Func<T, object>>(Expression.Convert(sortExpression, typeof(object)), prmExpression);
        return sortDirection == SortDirection.Ascending ?
            list.AsQueryable<T>().OrderBy<T, object>(lambda).ToList() :
            list.AsQueryable<T>().OrderByDescending<T, object>(lambda).ToList();
    }
}


What is the Expression.Convert() part for?
You may have noticed the code does a conversion on the sort expression that we provide:

Expression.Convert(sortExpression, typeof(object))

You may wonder why this is necessary as you are providing a string for the sortExpression parameter. However, it is important to remember that this isn't the type that is being specified in the expression tree, it is the type of the property on the object that is being sorted.

If you are sorting by MyObject.Name (where Name is a string property) then the type is string. However, if you are sorting by MyObject.Date (where Date is a DateTime) then this type needs to be a Date, not a string. That is why we do Expression.Convert(sortExpression, typeof(object)). We downcast to object to avoid a type mismatch problem in the evaluated expression tree.


Sample Listing
The following is a sample listing for a console application. Just remember to add a reference to System.Web as I use the SortDirection class from System.Web.UI.WebControls. Just use a different type if you end up using this outside of a web application.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Web.UI.WebControls;

namespace DynamicOrderBy
{
class Program
{
    static void Main(string[] args)
    {
        IList<MyObject> list = new List<MyObject>();
        list.Add(new MyObject { Name = "Name3", Address = "Address3" });
        list.Add(new MyObject { Name = "Name1", Address = "Address1" });
        list.Add(new MyObject { Name = "Name2", Address = "Address2" });

        var prm = Expression.Parameter(typeof(MyObject), "root");
        IList<MyObject> sortedList = new Sorter<MyObject>().Sort(list, prm, "Name", SortDirection.Ascending);

        Console.WriteLine("Sorting simple list:");
        foreach (MyObject obj in sortedList)
            Console.WriteLine(String.Format("{0} : {1}", obj.Name, obj.Address));
        Console.WriteLine(String.Empty);

        IList<MyComplexObject> complexList =
            new List<MyComplexObject>();
        complexList.Add(new MyComplexObject { Detail = new MyObject { Name = "Name3", Address = "Address3" } });
        complexList.Add(new MyComplexObject { Detail = new MyObject { Name = "Name1", Address = "Address1" } });
        complexList.Add(new MyComplexObject { Detail = new MyObject { Name = "Name2", Address = "Address2" } });

        var prmComplex = Expression.Parameter(typeof(MyComplexObject), "root");
        MemberExpression keySelectExpr =
            Expression.Property(Expression.Property(prmComplex, "Detail"), "Name");
        IList<MyComplexObject> sortedComplexList = new Sorter<MyComplexObject>().Sort(complexList, prmComplex, keySelectExpr, SortDirection.Ascending);

        Console.WriteLine("Sorting complex list:");
        foreach (MyComplexObject obj in sortedComplexList)
            Console.WriteLine(String.Format("{0} : {1}", obj.Detail.Name, obj.Detail.Address));

        Console.WriteLine(String.Empty);
        Console.WriteLine("Press any key to exit...");
        Console.ReadLine();
    }
}

public class MyObject
{
    public string Name { get; set; }
    public string Address { get; set; }
}

public class MyComplexObject
{
    public MyObject Detail { get; set; }
}

/// <summary>
/// A generic sorter class used to wrap the LINQ OrderBy functions.
/// </summary>
/// <typeparam name="T">The <see cref="System.Type"/> of object being sorted.</typeparam>
public class Sorter<T>
{
    /// <summary>
    /// Sorts a list of type T.
    /// </summary>
    /// <param name="list">The list to sort.</param>
    /// <param name="prmExpression">The expression defining the parameter to supply to the lambda expression.</param>
    /// <param name="sortExpression">The name of the property on the parameter object to sort by.
    /// <param name="sortDirection">The direction in which to sort the objects.</param>
    /// <returns>The sorted list.</returns>
    public List<T> Sort(
        IEnumerable<T> list,
        ParameterExpression prmExpression,
        string sortExpression,
        SortDirection sortDirection) {
        var lambda = Expression.Lambda<Func<T, object>>(Expression.Convert(Expression.Property(prmExpression, sortExpression), typeof(object)), prmExpression);
        return sortDirection == SortDirection.Ascending ?
            list.AsQueryable<T>().OrderBy<T, object>(lambda).ToList() :
            list.AsQueryable<T>().OrderByDescending<T, object>(lambda).ToList();
    }

    /// <summary>
    /// Sorts a list of type T.
    /// </summary>
    /// <param name="list">The list to sort.</param>
    /// <param name="prmExpression">The expression defining the parameter to supply to the lambda expression.</param>
    /// <param name="keySelectionExpression">
    /// A <see cref="MemberExpression"/> that identifies a property on an object in the supplied <param name="list"/> that is used to
    /// perform the sort.
    /// </param>
    /// <param name="sortDirection">The direction in which to sort the objects.</param>
    /// <returns>The sorted list.</returns>
    public List<T> Sort(
        IEnumerable<T> list,
        ParameterExpression prmExpression,
        MemberExpression sortExpression,
        SortDirection sortDirection) {
        var lambda = Expression.Lambda<Func<T, object>>(Expression.Convert(sortExpression, typeof(object)), prmExpression);
        return sortDirection == SortDirection.Ascending ?
            list.AsQueryable<T>().OrderBy<T, object>(lambda).ToList() :
            list.AsQueryable<T>().OrderByDescending<T, object>(lambda).ToList();
    }
}
}