我想为PLINQ bild自定义OrderBy,但我不知道如何。
对于IQueryable,使用可以使用以下代码:
public static class QueryableExtensions
{
public static IQueryable<T> OrderBy<T>(this IQueryable<T> source, string sortProperty, ListSortDirection sortOrder)
{
var type = typeof(T);
var property = type.GetProperty(sortProperty);
var parameter = Expression.Parameter(type, "p");
var propertyAccess = Expression.MakeMemberAccess(parameter, property);
var orderByExp = Expression.Lambda(propertyAccess, parameter);
var typeArguments = new Type[] { type, property.PropertyType };
var methodName = sortOrder == ListSortDirection.Ascending ? "OrderBy" : "OrderByDescending";
var resultExp = Expression.Call(typeof(Queryable), methodName, typeArguments, source.Expression, Expression.Quote(orderByExp));
return source.Provider.CreateQuery<T>(resultExp);
}
}
但对于ParallelQuery,没有这样的属性Provider和Expresss。 有人知道该怎么做吗?
public static class QueryableExtensions
{
public static ParallelQuery<T> OrderBy<T>(this ParallelQuery<T> source, string sortProperty, ListSortDirection sortOrder)
{
...
}
}
答案 0 :(得分:0)
只需在并行查询上调用AsQueryable
,然后在完成后调用AsParallel
以获取并行查询:
public static ParallelQuery<T> OrderBy<T>(this ParallelQuery<T> source,
string sortProperty, ListSortDirection sortOrder)
{
return source.AsQueryable()
.OrderBy(sortProperty, sortOrder)
.AsParallel();
}
答案 1 :(得分:0)
使用IQueryable
,您不需要Provider
,这足以创建表达式,然后直接致电OrderBy
/ OrderByDescending
。唯一的问题是OrderBy()
在排序属性的类型中是通用的,您不知道(非静态)。
您可以使用反射调用OrderBy()
来解决这个问题。或者您可以使用dynamic
:
public static IQueryable<T> OrderBy<T>(this IQueryable<T> source, string sortProperty, ListSortDirection sortOrder)
{
var type = typeof(T);
var property = type.GetProperty(sortProperty);
var parameter = Expression.Parameter(type, "p");
var propertyAccess = Expression.MakeMemberAccess(parameter, property);
var orderByExp = Expression.Lambda(propertyAccess, parameter);
if (sortOrder == ListSortDirection.Ascending)
{
return Queryable.OrderBy(source, (dynamic)orderByExp);
}
else
{
return Queryable.OrderByDescending(source, (dynamic)orderByExp);
}
}
您可以使用与PLINQ完全相同的内容:
public static ParallelQuery<T> OrderBy<T>(this ParallelQuery<T> source, string sortProperty, ListSortDirection sortOrder)
{
var type = typeof(T);
var property = type.GetProperty(sortProperty);
var parameter = Expression.Parameter(type, "p");
var propertyAccess = Expression.MakeMemberAccess(parameter, property);
var orderByFunc = Expression.Lambda(propertyAccess, parameter).Compile();
if (sortOrder == ListSortDirection.Ascending)
{
return ParallelEnumerable.OrderBy(source, (dynamic)orderByFunc);
}
else
{
return ParallelEnumerable.OrderByDescending(source, (dynamic)orderByFunc);
}
}