Dynamic OrderBy // InvalidOperationException: универсальный метод ThenByDescending для типа «System.Linq.Queryable» не совместим - PullRequest
0 голосов
/ 26 июня 2019

Я пытаюсь создать динамический метод OrderBy, который я могу вызывать неоднократно, к сожалению, я продолжаю получать ту же ошибку, несмотря на реализацию кода, который, как сообщалось, исправляет ее.

Я несколько раз анализировал свой код, ссылаясь на два сообщения SO, о которых сообщалось, что они работают; Нет универсального метода ThenBy и Нет универсального метода «ThenBy» для типа «System.Linq.Queryable»

Независимо от того, что я делаю, я всегда получаю сообщение об ошибке, даже если я копирую и вставляю их реализации прямо в мой код

Ошибка:

InvalidOperationException:

No generic method 'ThenByDescending' 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.

Мой метод:

public static IOrderedQueryable<TEntity> OrderBy<TEntity>(this IOrderedQueryable<TEntity> source, string orderByProperty, bool desc, bool then)
{
    var command = (then ? "Then" : "Order") + (desc ? "ByDescending" : "By");

    var entityType = typeof(TEntity);
    var entityParameter = Expression.Parameter(entityType, "x");

    var property = entityType.GetProperty(orderByProperty);

    var propertyAccess = Expression.MakeMemberAccess(entityParameter, property);
    var orderByExpression = Expression.Lambda(propertyAccess, entityParameter);

    var resultExpression =
        Expression.Call(typeof(Queryable), command, new Type[] { entityType, property.PropertyType }, source.Expression, Expression.Quote(orderByExpression));

    return (IOrderedQueryable<TEntity>)source.Provider.CreateQuery<TEntity>(resultExpression);
}

Метод вызова

public IQueryable<T> SortQuery(IQueryable<T> query, Dictionary<string, char> sorts, Dictionary<string, string> sortableProperties)
{
    var count = 0;

    foreach (var s in sorts)
        if (!string.IsNullOrWhiteSpace(s.Key) && new[] {'A', 'D'}.Contains(char.ToUpper(s.Value)))
            query = ((IOrderedQueryable<T>)query).OrderBy(sortableProperties[s.Key], char.ToUpper(s.Value) == 'D', count++ == 0);

    return query;
}

Если кто-нибудь сможет пролить свет на это, будет очень признателен, я рву волосы более 3 часов!

1 Ответ

1 голос
/ 27 июня 2019

Взломано, проблема была в том, что переданный Queryable был просто IQueryable, а не IOrderedQueryable - Приведение не работает, оно должно быть IOrderedQueryable.

public IOrderedQueryable<T> SortQuery(IQueryable<T> query, Dictionary<string, char> sorts)
{
    var count = 0;

    var orderedQuery = query.OrderBy(x => true); // This is the fix!

    foreach (var s in sorts)
        if (!string.IsNullOrWhiteSpace(s.Key) && new[] {'A', 'D'}.Contains(char.ToUpper(s.Value)))
            orderedQuery = orderedQuery.OrderBy(this.SortFields[s.Key], char.ToUpper(s.Value) == 'D', count++ == 0);

    return orderedQuery;
}

Благодарность @IvanStoev за то, что я выбрал правильный путь.

...