Click here to Skip to main content
15,879,239 members
Articles / Programming Languages / C#
Tip/Trick

Building OrderBy Lambda Expression from Property Name in C#

Rate me:
Please Sign up or sign in to vote.
4.92/5 (11 votes)
10 Sep 2014CPOL1 min read 48.4K   232   21   4
Let's make a lambda expression from a property name of a particular entity, and use it for OrderBy shorting

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.

C++
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:

C++
/*When using lambda expression*/
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:

C++
/*But we needed to do*/
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.

C++
Db.Phones                    //source is IQueryable<Phone>
Db.Phones.AsEnumerable()    //source is IEnumerable<Phone>

Utility Class

Here is the utility class, which will be used to make lambda expression from a property name for a particular entity.

C++
public static class Utility
{
    //makes expression for specific prop
    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));   //important to use the Expression.Convert
        return Expression.Lambda<Func<TSource, object>>(conversion, param);
    }

    //makes deleget for specific prop
    public static Func<TSource, object> GetFunc<TSource>(string propertyName)
    {
        return GetExpression<TSource>(propertyName).Compile();  //only need compiled expression
    }

    //OrderBy overload
    public static IOrderedEnumerable<TSource> 
    OrderBy<TSource>(this IEnumerable<TSource> source, string propertyName)
    {
        return source.OrderBy(GetFunc<TSource>(propertyName));
    }

    //OrderBy overload
    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:

C++
List<Phone> orderedByPrice = null;
List<Phone> orderedByBrand = null;

/*When source is IQueryable*/
orderedByPrice = Db.Phones.OrderBy("Price").ToList();
orderedByBrand = Db.Phones.OrderBy("Brand").ToList();

/*When source is IEnumerable*/
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

  1. Yes, there could be something which I misunderstood or presented. So if you find anything, just let me know.
  2. 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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Bangladesh Bangladesh
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralNice Pin
Nitol Neophyte11-Sep-14 22:51
Nitol Neophyte11-Sep-14 22:51 
GeneralRe: Nice Pin
DiponRoy11-Sep-14 23:33
DiponRoy11-Sep-14 23:33 
QuestionDynamicLinq Pin
jogibear998810-Sep-14 19:10
jogibear998810-Sep-14 19:10 
AnswerRe: DynamicLinq Pin
DiponRoy11-Sep-14 4:30
DiponRoy11-Sep-14 4:30 
AnswerMessage Closed Pin
11-Sep-14 8:47
Member 1027706711-Sep-14 8:47 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.