I used the following methods to build Order By Expression . Source source
This is really a stain. The disadvantage is that it only works if the property is a string .
How can I make it accept different types of properties without creating a bunch of methods for different data types?
public static bool PropertyExists<T>(string propertyName) { return typeof (T).GetProperty(propertyName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance) != null; } public static Expression<Func<T, string>> GetPropertyExpression<T>(string propertyName) { if (typeof(T).GetProperty(propertyName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance) == null) { return null; } var paramterExpression = Expression.Parameter(typeof(T)); return (Expression<Func<T, string>>)Expression.Lambda( Expression.PropertyOrField(paramterExpression, propertyName), paramterExpression); }
Using
// orderBy can be either Name or City. if (QueryHelper.PropertyExists<Club>(orderBy)) { var orderByExpression = QueryHelper.GetPropertyExpression<Club>(orderBy); clubQuery = clubQuery.OrderBy(orderByExpression); } else { clubQuery = clubQuery.OrderBy(c => c.Id); }
Problem
public class Club { public int Id { get; set; } public string Name { get; set; } public string City { get; set; } public DateTime CreateDate { get; set; } <= this won't work }
My current approach (too many if statements)
public static Expression<Func<TSource, TKey>> GetPropertyExpression<TSource, TKey>(string propertyName) { if (typeof (TSource).GetProperty(propertyName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance) == null) { return null; } var paramterExpression = Expression.Parameter(typeof (TSource)); return (Expression<Func<TSource, TKey>>) Expression.Lambda(Expression.PropertyOrField( paramterExpression, propertyName), paramterExpression); }
The downside is that in the end I get a lot of if statements for each data type.
if (QueryHelper.PropertyExists<Club>(orderBy)) { if(orderBy == "CreateDate") { var orderByExpression = GetPropertyExpression<Club, DateTime>(orderBy); ... } else if(orderBy == "Name" || orderBy == "City") { var orderByExpression = GetPropertyExpression<Club, string>(orderBy); ... } ... } else { clubQuery = clubQuery.OrderBy(c => c.Id); }