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 }