以编程方式创建用于对IQueryable进行排序的谓词

时间:2019-09-09 18:58:46

标签: c# linq expression

我想为space-between接口创建一个通用扩展方法,该方法需要一些字符串输入并生成一个auto输出。

我尝试以编程方式创建IQueryable<T>,但只能在运行时确定IOrderedQueryable<T>

这是我到目前为止提出的实现方法

Expression<Func<T,TKey>>

对于上下文,TKey字段存在于将要调用Sort方法的所有类型T上

这不能成功编译(如预期的那样),但是我不知道如何在运行时指定输出类型。

1 个答案:

答案 0 :(得分:1)

在这种情况下,最简单的方法是使用OrderBy / OrderByDescending方法构建表达式并创建新的可查询内容:

    public static IOrderedQueryable<T> Sort<T>(this IQueryable<T> query, string sort) where T : class
    {
        Type type = typeof(T);
        ParameterExpression param = Expression.Parameter(type, "x");
        var (isDescending, normalizedSortParam) = NormalizeSortParam(sort);
        MemberExpression propertyExpression;
        try
        {
            propertyExpression = Expression.PropertyOrField(param, normalizedSortParam);
        }
        catch(ArgumentException)
        {
            propertyExpression = Expression.Property(param, "Id");
        }

        Type outputType = propertyExpression.Type;
        LambdaExpression filterExpression = Expression.Lambda(propertyExpression, param);

        // Call OrderBy or OrderByDescending on original query expression
        MethodCallExpression orderedExpression = Expression.Call(
            typeof(Queryable),
            isDescending ? "OrderByDescending" : "OrderBy",
            new []{ typeof(T), outputType },
            new [] { query.Expression, filterExpression }
        );

        // Create new query from orderedExpression 
        return (IOrderedQueryable<T>)query.Provider.CreateQuery<T>(orderedExpression);
    }