I'm trying to dynamically use reflection to do an OrderBy on whether a given sortColumn (string) is null or not, a ThenBy on the sortColumn value, and a ThenBy on hard-coded columns. Like so:
if (!String.IsNullOrEmpty(sortColumn)) {
var descending = sortDirection == "desc";
views = views.AsQueryable()
.OrderByNull<ToDoView>(sortColumn, true)//extension method
.OrderBy<ToDoView>(sortColumn, descending, true)//extension method
.ThenBy(v => v.summary ?? v.description).ToList();
}
Using other SO answers, I was able to get the OrderBy extension method to work:
public static IOrderedQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> source, string orderByProperty, bool desc, bool thenBy = false) {
string command = desc ? "OrderByDescending" : "OrderBy";
if (thenBy)
command = desc ? "ThenByDescending" : "ThenBy";
var type = typeof(TEntity);
var property = type.GetProperty(orderByProperty);
var parameter = Expression.Parameter(type, "p");
var propertyAccess = Expression.MakeMemberAccess(parameter, property);
var orderByExpression = Expression.Lambda(propertyAccess, parameter);
var resultExpression = Expression.Call(typeof(Queryable), command, new Type[] { type, property.PropertyType },
source.Expression, Expression.Quote(orderByExpression));
return (IOrderedQueryable<TEntity>)source.Provider.CreateQuery<TEntity>(resultExpression);
}
Here is my OrderByNull extension method:
public static IOrderedQueryable<TEntity> OrderByNull<TEntity>(this IQueryable<TEntity> source, string orderByProperty, bool desc, bool thenBy = false) {
string command = desc ? "OrderByDescending" : "OrderBy";
if (thenBy)
command = desc ? "ThenByDescending" : "ThenBy";
var type = typeof(TEntity);
var property = type.GetProperty(orderByProperty);
var parameter = Expression.Parameter(type, "p");
var target = Expression.Constant(null, type);
var equalsMethod = Expression.Call(Expression.Property(parameter, orderByProperty), "Equals", null, target);
var orderByExpression = Expression.Lambda(equalsMethod, parameter);
var resultExpression = Expression.Call(typeof(Queryable), command, new Type[] { type, property.PropertyType },
source.Expression, Expression.Quote(orderByExpression));
return (IOrderedQueryable<TEntity>)source.Provider.CreateQuery<TEntity>(resultExpression);
}
When executing this extension method, the orderByExpression evaluates to:
{p => p.listName.Equals(null)}
However, when trying to set the resultExpression it throws an exception:
System.InvalidOperationException: 'No generic method 'OrderByDescending' on type 'System.Linq.Queryable' is compatible with the supplied type arguments and arguments. No type arguments should be provided if the method is non-generic. '
I'm not really sure how to fix this, as the expression looks right to me. Any ideas?
Aucun commentaire:
Enregistrer un commentaire