My Technical Notes

Wednesday, 16 June 2010

NullsLast Extension method for Property Name

Continuing on from my previous post regarding sorting a column by putting the nulls at the end rather than at the beginning, I have found a need to write a NullsLast extension method that takes a string which represents the property's name instead of an expression which represents the property. This was needed for use with MvcContrib's Html Grid for which one can use the OrderBy extension method found in MvcContrib.Sorting namespace.

The way that you would want to use the extension method would be to specify the name of the property as a string:


projects.OrderBy("Name", SortDirection.Ascending).NullsLast("Name");

It turns out that this method's definition is very similar to the definition of earlier NullsLast Definition with the exception that we need to use reflection to get the PropertyInfo using the property name string parameter. We then proceed as usual to construct a equals expression using the property and the null constant and then call OrderBy with the newly constructed (x => x.property == null) expression:


public static IQueryable<TSource> NullsLast<TSource>(this IQueryable<TSource> query, string propertyName)
{
    if (string.IsNullOrEmpty(propertyName)) return query;

    var type = typeof(TSource);
    var property = type.GetProperty(propertyName);

    if (property == null)
    {
        throw new InvalidOperationException(string.Format("Could not find a property called '{0}' on type {1}", propertyName, type));
    }

    if (!property.PropertyType.IsClass && !property.PropertyType.IsGenericType)
    {
        return query;
    }

    var nullExpr = Expression.Constant(null);
    var parameter = Expression.Parameter(type, "p");
    var propertyAccess = Expression.MakeMemberAccess(parameter, property);
    var equalExpr = Expression.Equal(propertyAccess, nullExpr);
    var lamdba = Expression.Lambda<Func<TSource, bool>>(equalExpr, parameter);
    return query.OrderBy(lamdba);
}

No comments: