Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/256.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/88.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 以编程方式创建用于对IQueryable排序的谓词_C#_Linq_Expression - Fatal编程技术网

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

C# 以编程方式创建用于对IQueryable排序的谓词,c#,linq,expression,C#,Linq,Expression,我想为IQueryable接口创建一个通用扩展方法,它将接受一些字符串输入并生成一个IOrderedQueryable输出 我曾尝试通过编程方式创建表达式,但TKey只能在运行时确定 这是我到目前为止提出的实现 publicstaticiorderedqueryable排序(this IQueryable this,string排序),其中T:class { var类型=类型(T); var param=表达式参数(类型为“x”); var(isDescending,normalizedSort

我想为
IQueryable
接口创建一个通用扩展方法,它将接受一些字符串输入并生成一个
IOrderedQueryable
输出

我曾尝试通过编程方式创建
表达式
,但
TKey
只能在运行时确定

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

publicstaticiorderedqueryable排序(this IQueryable this,string排序),其中T:class
{
var类型=类型(T);
var param=表达式参数(类型为“x”);
var(isDescending,normalizedSortParam)=NormalizeSortParam(sort);
MemberExpression propertyExpression;
尝试
{
propertyExpression=Expression.PropertyOrField(param,normalizedSortParam);
}
捕获(异常)
{
propertyExpression=Expression.Property(param,“Id”);
}
var outputType=propertyExpression.Type;
var filterExpression=Expression.Lambda(propertyExpression,param);
return isDescending?This.OrderByDescending(filterExpression):This.OrderBy(filterExpression);
}
对于上下文,
Id
字段存在于将调用排序方法的所有类型T上


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

在这种情况下,最简单的方法是使用
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);
    }
publicstaticiorderedqueryable排序(此IQueryable查询,字符串排序),其中T:class
{
类型=类型(T);
ParameterExpression param=表达式参数(类型为“x”);
var(isDescending,normalizedSortParam)=NormalizeSortParam(sort);
MemberExpression propertyExpression;
尝试
{
propertyExpression=Expression.PropertyOrField(param,normalizedSortParam);
}
捕获(异常)
{
propertyExpression=Expression.Property(param,“Id”);
}
类型outputType=propertyExpression.Type;
LambdaExpression filterExpression=Expression.Lambda(propertyExpression,param);
//对原始查询表达式调用OrderBy或OrderByDescending
MethodCallExpression orderedExpression=Expression.Call(
类型(可查询),
isDescending?“OrderByDescending”:“OrderBy”,
新[]{typeof(T),outputType},
新[]{query.Expression,filterExpression}
);
//从orderedExpression创建新查询
return(IOrderedQueryable)query.Provider.CreateQuery(orderedExpression);
}

在过去,我对T使用了另一种类型约束,例如,其中T:IIdentifiable,class。(具有id属性/get访问器的IIIdentifiable接口)请参阅for
Expression.Lambda
-其中一些接口将类型作为运行时参数,而不是泛型类型参数。您可能还需要通过反射来调用
OrderBy
,但随后可以将结果转换回
IOrderedQueryable