.NET, Architecture, ALM, Cloud
Voici un exemple dimplémentation pour ajouter une méthode d'extension sur IQueryable<TSource> pour effectuer vos tris sur un nom de membre (sans méthode lambda) et préciser la direction (éviter d'avoir à appeller dans un cas le "OrderBy" ou dans l'autre le "OrderByDescending") :
public static class QueryableExtensions
{
public static IOrderedQueryable<TSource> OrderBy<TSource>(
this IQueryable<TSource> query,
string dataMember,
ListSortDirection direction)
{
string orderByMethodName = (direction == ListSortDirection.Ascending) ? "OrderBy" : "OrderByDescending";
PropertyInfo property = typeof(TSource).GetProperty(dataMember);
dynamic sortExpression = BuildOrderByExpression<TSource>(dataMember, property.PropertyType);
MethodInfo orderByMethod = typeof(System.Linq.Queryable).GetMethods()
.Single(Method => Method.Name == orderByMethodName
&& Method.GetParameters().Count() == 2
&& Method.GetParameters()[1].ParameterType.ToString() == "System.Linq.Expressions.Expression`1[System.Func`2[TSource,TKey]]"
);
return
(IOrderedQueryable<TSource>)orderByMethod.MakeGenericMethod(typeof(TSource), property.PropertyType)
.Invoke(query, new object[2] { query, sortExpression });
}
private static dynamic BuildOrderByExpression<TSource>(string member, Type memberType)
{
return typeof(QueryableExtensions)
.GetMethod("BuildOrderByExpression", BindingFlags.NonPublic | BindingFlags.Static, null, new Type[1] { typeof(string) }, null)
.MakeGenericMethod(typeof(TSource), memberType).Invoke(null, new object[1] { member });
}
private static Expression<Func<TSource, Key>> BuildOrderByExpression<TSource, Key>(string member)
{
var param = Expression.Parameter(typeof(TSource), "entity");
return Expression.Lambda<Func<TSource, Key>>(
Expression.Property(param, member),
param);
}
}
Et un test unitaire :