Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/323.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# Can';在可查询项上找不到OrderBy,请使用;提供的参数";。_C#_Linq_Expression Trees - Fatal编程技术网

C# Can';在可查询项上找不到OrderBy,请使用;提供的参数";。

C# Can';在可查询项上找不到OrderBy,请使用;提供的参数";。,c#,linq,expression-trees,C#,Linq,Expression Trees,我想使用一种方法对列表进行排序: private static IQueryable<T> BuildQuery<T>(IQueryable<T> query, string methodName, Expression<Func<T, object>> prop

我想使用一种方法对列表进行排序:

private static IQueryable<T> BuildQuery<T>(IQueryable<T> query, 
                                           string methodName, 
                                           Expression<Func<T, object>> property)             
    {
        var typeArgs = new[] { query.ElementType, property.Body.Type };

        methodCall = Expression.Call(typeof (Queryable),
                                                  methodName,
                                                  typeArgs,
                                                  query.Expression,
                                                  property);

        return query.Provider.CreateQuery<T>(methodCall);
    }
有人能看到我遗漏了什么吗

编辑:

我尝试了另一个Expression.Call()重载,但得到了相同的异常:

private static IQueryable<T> BuildQuery<T>(IQueryable<T> query, string methodName, Expression<Func<T, object>> propertyExpression)             
    {
        var methodCall = Expression.Call(query.Expression,
                                         methodName,
                                         new[] {query.ElementType, property.Body.Type},
                                         new[] {propertyExpression});

        return query.Provider.CreateQuery<T>(methodCall);
    }
private静态IQueryable构建查询(IQueryable查询、字符串方法名、表达式属性Expression)
{
var methodCall=Expression.Call(query.Expression,
方法名,
新[]{query.ElementType,property.Body.Type},
新[]{propertyExpression});
返回query.Provider.CreateQuery(methodCall);
}

由于您希望属性选择器表达式动态地进行适当的调用,因此必须为其创建新的表达式。您不能按原样使用提供的选择器,因为它当前已键入
Expression
,并且未返回您的特定类型
Expression
。您可以通过将调用的类型参数更改为accept
object
来编译它,但它不会按预期工作,因为它将进行对象引用比较(并且您的LINQ提供程序可能会拒绝它)

要重新创建选择器表达式,可以执行以下操作:

private static IQueryable<T> BuildQuery<T>(
    IQueryable<T> query,
    string methodName,
    Expression<Func<T, object>> property)
{
    var typeArgs = new[] { query.ElementType, property.Body.Type };
    var delegateType = typeof(Func<,>).MakeGenericType(typeArgs);
    var typedProperty = Expression.Lambda(delegateType, property.Body, property.Parameters);

    var methodCall = Expression.Call(
        typeof(Queryable),
        methodName,
        typeArgs,
        query.Expression,
        typedProperty);

    return query.Provider.CreateQuery<T>(methodCall);
}
私有静态IQueryable构建查询(
可查询的查询,
字符串methodName,
表达式(属性)
{
var typeArgs=new[]{query.ElementType,property.Body.Type};
var delegateType=typeof(Func).MakeGenericType(typeArgs);
var typedProperty=Expression.Lambda(delegateType,property.Body,property.Parameters);
var methodCall=Expression.Call(
类型(可查询),
方法名,
typeArgs,
query.Expression,
类型属性);
返回query.Provider.CreateQuery(methodCall);
}
一个很好的替代方法是将属性类型也设置为泛型。这样,您将从一开始就得到一个适当的强类型选择器

private static IQueryable<TSource> BuildQuery<TSource, TProperty>(
    IQueryable<TSource> query,
    string methodName,
    Expression<Func<TSource, TProperty>> property)
{
    var typeArguments = property.Type.GetGenericArguments();

    var methodCall = Expression.Call(
        typeof(Queryable),
        methodName,
        typeArguments,
        query.Expression,
        property);

    return query.Provider.CreateQuery<TSource>(methodCall);
}
私有静态IQueryable构建查询(
可查询的查询,
字符串methodName,
表达式(属性)
{
var typeArguments=property.Type.GetGenericArguments();
var methodCall=Expression.Call(
类型(可查询),
方法名,
类型参数,
query.Expression,
财产);
返回query.Provider.CreateQuery(methodCall);
}

请给我看一下
我先前存在的查询的构造好吗?我在方法调用上方添加了它。就是这样。你说的很有道理。我粘贴了你的代码,测试开始运行。谢谢你的回答。我添加了另一个替代方法来重新创建表达式。严格来说,不必只将源代码设置为泛型,您可以将这两种类型都设置为泛型。您的选择将对其他类型有好处,而且它肯定会使函数更加灵活。但不幸的是,我无法将属性类型设置为泛型,因为直到运行时我才知道该类型。啊,好的。我猜这意味着你要动态地生成属性选择器。如果您总是在编译时知道表达式,那么这仍然是一个很好的补充。
private static IQueryable<T> BuildQuery<T>(
    IQueryable<T> query,
    string methodName,
    Expression<Func<T, object>> property)
{
    var typeArgs = new[] { query.ElementType, property.Body.Type };
    var delegateType = typeof(Func<,>).MakeGenericType(typeArgs);
    var typedProperty = Expression.Lambda(delegateType, property.Body, property.Parameters);

    var methodCall = Expression.Call(
        typeof(Queryable),
        methodName,
        typeArgs,
        query.Expression,
        typedProperty);

    return query.Provider.CreateQuery<T>(methodCall);
}
private static IQueryable<TSource> BuildQuery<TSource, TProperty>(
    IQueryable<TSource> query,
    string methodName,
    Expression<Func<TSource, TProperty>> property)
{
    var typeArguments = property.Type.GetGenericArguments();

    var methodCall = Expression.Call(
        typeof(Queryable),
        methodName,
        typeArguments,
        query.Expression,
        property);

    return query.Provider.CreateQuery<TSource>(methodCall);
}