If you use LINQ to retrieve data and display this data in a grid, you may have come across the problem of allowing the user to control how the data is sorted. Users always want to be able to sort data on their own.

GridView makes it easy to wire up an event handler or trigger an action to handle the sorting. The problem is that such sorting is not necessarily so straightforward with LINQ.

A common approach is to hard code a giant if statement listing out the possibilities:

1: public IQueryable<FileImport> SortFiles

2: (IQueryable<FileImport> files,

3: string orderBy)

4: {

5: if (orderBy == "FileName")

6: files = files.OrderBy(o => o.FileName);

7: if (orderBy == "ImportDate")

8: files = files.OrderBy(o => o.ImportDate);

9: . . .

10: return files;

11: }

While this is dynamic, it only works for the one data type, forces a brittle dependency on the property names, and has to be changed whenever a new property is added.

A better approach may be to use ExpressionTrees and dynamically build up the whole call to the OrderBy function.

Consider this extension method:

1: publicstatic IOrderedQueryable<TSource>

2: GenericEvaluateOrderBy<TSource>

3: (this IQueryable<TSource> query,

4: string propertyName)

5: {

6: var type = typeof (TSource);

7: var parameter = Expression.Parameter(type, "p");

8: var propertyReference = Expression.Property(pe, propertyName);

9: var sortExpression = Expression.Call(

10: typeof (Queryable),

11: "OrderBy",

12: new Type[] {type},

13: null,

14: Expression.Lambda<Func<TSource, bool>>

15: (propertyReference, new[] { parameter }));

16: return query.Provider.CreateQuery<TSource>(sortExpression);

17: }

With this method in place, you can sort by any column on any ViewModel:

1: if (!string.IsNullOrEmpty(sortExpression))

2: query = query.GenericEvaluateOrderBy(sortExpression);

3: return query;

In this case the sortExpression variable would come from the Sort method on the GridView.