Pages

Friday, April 27, 2018

How to OrderBy with the property name using LINQ?

In this post we are gonna re-invent the LINQ's OrderBy extension method.
The implementation of OrderBy allows us to pass lambda expression in the form: x => x.Name
so to order list of students by name, you do the following:
var orderedStudents = allStudents.OrderBy(s => s.Name);
but what if you want to order dynamically by the property name ("Name") in run-time (from data storage source for example)
what would you do, do you use switch-case?
Nah, there's a much more better solution than this and it's 3~5 lines of code!

Lambda Expressions

We need the lambda expression to be replaced by a string parameter, fortunately it's easy building up a lambda expression by the property name and the object type.

Let's break down the lambda expression passed to OrderBy : x => x.Name
x is the parameter and it's of type T which get inferred in compile time from the invoked list.
Name is the member

so let's create them:

Parameter:
        var param = Expression.Parameter(typeof(Foo), "p");
Member:
        var member = Expression.Property(param, "Name");
then assemble the lambda expression:
        var lambda = Expression.Lambda<Func<Foo, object>>(member, param);
lambda will only work on IQueryable because it's of type Expression<Func<Foo, object>>
to work on IEnumerable we need to compile it:
         lambda.Compile();

the following is the complete code:

public static class NiceLinq
{
public static IEnumerable<T> OrderBy<T>(this IEnumerable<T> notOrderedList, string propertyName)
{
var lambda = GetLambda<T>(propertyName);
var orderedList = notOrderedList.OrderBy(lambda);
return orderedList;
}
private static Func<T, object> GetLambda<T>(string propertyName)
{
var param = Expression.Parameter(typeof(T), "p");
var member = Expression.Property(param, propertyName);
Expression conversion = Expression.Convert(member, typeof(object)); //explicit casting is a must
var lambda = Expression.Lambda<Func<T, object>>(conversion, param);
return lambda.Compile();
}
}
public class Program
{
public static void Main(String[] args)
{
//some code from data storage source
var orderedStudents = allStudents.OrderBy("Name");
}
}
view raw OrderBy.cs hosted with ❤ by GitHub





Dynamically load jndi.properties when JMeter is running

An approach to having all test configurations in one place is using the jndi.properties file of JMeter. When maintaining many JMeter test su...