Introduction
Here in this post, we are going to see how to make a lambda expression from a property name of a particular entity, and use it for OrderBy shorting for both IQueryable and IEnumerable sources.
Background
Let’s say we have a model.
public class Phone
{
public double Price { get; set; }
public string Brand { get; set; }
}
And we have a data source Db.Phones, and for regular OrderBy shorting by property, we use:
Db.Phones.OrderBy(x => x.Price).ToList();
Db.Phones.OrderBy(x => x.Brand).ToList();
Now, we want to do this shorting with property name only, rather than using lambda expression, like:
Db.Phones.OrderBy("Price").ToList();
Db.Phones.OrderBy("Brand").ToList();
One interesting thing is the data source could be any among IQueryable or IEnumerable. So we have to consider both.
Db.Phones Db.Phones.AsEnumerable()
Utility Class
Here is the utility class, which will be used to make lambda expression from a property name for a particular entity.
public static class Utility
{
public static Expression<Func<TSource, object>> GetExpression<TSource>(string propertyName)
{
var param = Expression.Parameter(typeof(TSource), "x");
Expression conversion = Expression.Convert(Expression.Property
(param, propertyName), typeof(object)); return Expression.Lambda<Func<TSource, object>>(conversion, param);
}
public static Func<TSource, object> GetFunc<TSource>(string propertyName)
{
return GetExpression<TSource>(propertyName).Compile(); }
public static IOrderedEnumerable<TSource>
OrderBy<TSource>(this IEnumerable<TSource> source, string propertyName)
{
return source.OrderBy(GetFunc<TSource>(propertyName));
}
public static IOrderedQueryable<TSource>
OrderBy<TSource>(this IQueryable<TSource> source, string propertyName)
{
return source.OrderBy(GetExpression<TSource>(propertyName));
}
}
Here are the two overloads for OrderBy to handle both IEnumerable<TSource> and IQueryable<TSource>.
Using the Code
Now let’s test the overloads:
List<Phone> orderedByPrice = null;
List<Phone> orderedByBrand = null;
orderedByPrice = Db.Phones.OrderBy("Price").ToList();
orderedByBrand = Db.Phones.OrderBy("Brand").ToList();
orderedByPrice = Db.Phones.AsEnumerable().OrderBy("Price").ToList();
orderedByBrand = Db.Phones.AsEnumerable().OrderBy("Brand").ToList();
For a quick overview, check out https://dotnetfiddle.net/sEmFzq.
Limitations
- Yes, there could be something which I misunderstood or presented. So if you find anything, just let me know.
- I have tested this for simple properties (
string Name, int Id, etc.) as I have shown here. But if we have complex properties like (Processor Processor; where processor has name, and we want to do order by Processor.Name), it may collapse.
Find the Visual Studio 2010 solution in the attachment.