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.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.