我有一个IQueryable类型的集合,我需要根据一些动态排序字段对此进行排序。排序字段在列表内。
我编写以下方法来做到这一点。
public List<T> Order<T>(IQueryable<T> source, List<string> propertyNames)
{
if(propertyNames != null && propertyNames.Count > 0)
{
var param = Expression.Parameter(typeof(T), string.Empty);
var property = Expression.PropertyOrField(param, propertyNames[0]);
var sort = Expression.Lambda(property, param);
MethodCallExpression orderByCall = Expression.Call(typeof(Queryable),"OrderBy",new[] { property.Type },Expression.Quote(sort));
if(propertyNames.Count > 1)
{
foreach(var item in propertyNames)
{
param = Expression.Parameter(typeof(T), string.Empty);
property = Expression.PropertyOrField(param, item);
sort = Expression.Lambda(property, param);
orderByCall = Expression.Call(
typeof(Queryable),
"ThenBy", new[] { typeof(T), property.Type },
orderByCall,
Expression.Quote(sort));
}
}
var results = (IOrderedQueryable<T>)source.Provider.CreateQuery<T>(orderByCall);
if(results != null)
return results.ToList();
}
return null;
}
执行MethodCallExpression orderByCall = Expression.Call(typeof(Queryable),"OrderBy",new[] { property.Type },Expression.Quote(sort));
时出现异常
类型'System.Linq.Queryable'上没有通用方法'OrderBy'是 与提供的类型实参和实参兼容。没有类型 如果该方法是非泛型的,则应提供参数。
答案 0 :(得分:1)
对不起,我没有直接解决您的错误的方法。
这里是动态排序数据的另一种方法(“保持简单”)。
1)将这些扩展方法添加到项目中的某个地方
public static IOrderedQueryable<TSource> OrderBy<TSource, TProperty>(this IQueryable<TSource> source
, Expression<Func<TSource, TProperty>> expression, bool descending)
{
return !descending ? source.OrderBy(expression) : source.OrderByDescending(expression);
}
public static IOrderedQueryable<TSource> ThenBy<TSource, TProperty>(this IOrderedQueryable<TSource> source
, Expression<Func<TSource, TProperty>> expression, bool descending)
{
return !descending ? source.ThenBy(expression) : source.ThenByDescending(expression);
}
2)现在,您可以循环遍历属性名称列表,并在IQueryable上应用OrderBy / ThenBy。
其他想法:您可以调整方法,使其接受表达式而不是属性名称字符串。