C# ';无通用方法>';OrderByDescending';关于类型';System.Linq.Queryable';与提供的类型参数和参数兼容

C# ';无通用方法>';OrderByDescending';关于类型';System.Linq.Queryable';与提供的类型参数和参数兼容,c#,linq,reflection,C#,Linq,Reflection,我试图动态地使用反射对给定的sortColumn(字符串)是否为null执行OrderBy,对sortColumn值执行ThenBy,对硬编码列执行ThenBy。像这样: if (!String.IsNullOrEmpty(sortColumn)) { var descending = sortDirection == "desc"; views = views.AsQueryable() .OrderByNull<ToDoView>(sortColu

我试图动态地使用反射对给定的
sortColumn
(字符串)是否为null执行
OrderBy
,对
sortColumn
值执行
ThenBy
,对硬编码列执行
ThenBy
。像这样:

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();
}
这是我的
OrderByNull
扩展方法:

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);
}
但是,当尝试设置
resultExpression
时,它会引发异常:

System.invalidoOperationException
:“无泛型方法”
OrderByDescending
“on type”
System.Linq.Queryable
“与提供的类型参数和参数兼容。如果方法是非泛型的,则不应提供类型参数。'

我真的不知道如何解决这个问题,因为这个表达式在我看来是正确的。有什么想法吗


这是我最后的
OrderByNull
扩展方法,在接受答案的修复和使用equals逻辑解决
NullReferenceException
后:

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.Equal(Expression.Property(parameter, orderByProperty), Expression.Constant(null, typeof(object)));
    var orderByExpression = Expression.Lambda(equalsMethod, parameter);
    var resultExpression = Expression.Call(
        typeof(Queryable), 
        command, 
        new Type[] { type, typeof(bool) },
        source.Expression, 
        Expression.Quote(orderByExpression));
    return (IOrderedQueryable<TEntity>)source.Provider.CreateQuery<TEntity>(resultExpression);
}
公共静态IOrderedQueryable OrderByNull(此IQueryable源,
字符串orderByProperty,bool desc,bool thenBy=false){
string command=desc?“OrderByDescending”:“OrderBy”;
如果(然后)
command=desc?“ThenBy Descending”:“ThenBy”;
变量类型=类型(强度);
var property=type.GetProperty(orderByProperty);
var参数=表达式参数(类型为“p”);
var target=Expression.Constant(null,type);
var equalsMethod=Expression.Equal(Expression.Property(参数,orderByProperty),Expression.Constant(null,typeof(对象));
var orderByExpression=Expression.Lambda(equalsMethod,参数);
var resultExpression=Expression.Call(
类型(可查询),
指挥部,
新类型[]{Type,typeof(bool)},
来源.表达式,
Expression.Quote(orderByExpression));
返回(IOrderedQueryable)source.Provider.CreateQuery(resultExpression);
}

在失败的情况下,指定
属性.PropertyType
新类型[]{Type,property.PropertyType}
)作为被调用泛型方法
OrderBy
泛型参数,但选择器lambda结果类型(应与
TKey
匹配)是
bool
,因此有例外

要解决它,就要改变

new Type[] { type, property.PropertyType }

或更一般(可在两种方法中使用)


在失败的情况下,指定
property.PropertyType
newtype[]{Type,property.PropertyType}
)作为被调用泛型方法
OrderBy
泛型参数,但是选择器lambda结果类型(应该与
TKey
匹配)是
bool
,因此有例外

要解决它,就要改变

new Type[] { type, property.PropertyType }

或更一般(可在两种方法中使用)


表达式的结果类型是
bool
,而不是
property.PropertyType
。(顺便说一句,我怀疑提供者是否可以翻译它——您可能需要使用
Expression.Equal
,而不是调用
Equals
)表达式的结果类型是
bool
,而不是
property.PropertyType
。(顺便说一句,我怀疑提供者是否可以翻译它——您可能需要使用
Expression.Equal
,而不是调用
Equals
new Type[] { type, property.PropertyType }
new Type[] { type, typeof(bool) }
new Type[] { type, orderByExpression.ReturnType  }