Solution #3 is basically correct. You need to create and Expression on the fly. EF examines the expression to generate the SQL so plain lambda won't work. Here is my approach:
static Expression<Func<T,object>> CreateExpression<T>(string propertyName)
{
var type = typeof(T);
var property = type.GetProperty(propertyName);
var parameter = Expression.Parameter(type);
var access = Expression.Property(parameter, property);
var convert = Expression.Convert(access, typeof(object));
var function = Expression.Lambda<Func<T,object>>(convert, parameter);
return function;
}
And you can use it like this:
db.Pupil.OrderBy(CreateExpression<Pupil>>("Name"));
It's ironic if you think about it. All this is needed to wrap the property name only to allow the LINQ provider to extract it later in order to generate the ORDER BY <your property="" name=""> clause. Ok, there may be some mapping but anyway...
Edit
Please note that this doesn't work. If you remove the convert to object it will eventually work for reference types but not for value types.
var access = Expression.Property(parameter, property);
var function = Expression.Lambda<Func<T,object>>(access, parameter);