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.