mercredi 9 janvier 2019

'No generic method > 'OrderByDescending' on type 'System.Linq.Queryable' is compatible with the supplied type arguments and arguments

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