如何使用表达式树为PLINQ构建动态查询 [英] How to build dynamic query with expression tree for PLINQ

查看:88
本文介绍了如何使用表达式树为PLINQ构建动态查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为PLINQ定制定制的OrderBy,但我不知道该怎么做.

I want to bild customized OrderBy for PLINQ, but I don't know how to.

对于IQueryable,使用可以使用以下代码:

For IQueryable, use can use below code:

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.有人知道怎么做吗?

But for ParallelQuery, there's no such property Provider and Expresss. Does anybody know how to do?

public static class QueryableExtensions
{
    public static ParallelQuery<T> OrderBy<T>(this ParallelQuery<T> source, string sortProperty, ListSortDirection sortOrder)
    {
        ...
    }
}

推荐答案

使用 IQueryable ,您不需要 Provider ,就足以创建表达式并然后直接调用 OrderBy / OrderByDescending .唯一的问题是 OrderBy()在sorting属性的类型中是通用的,您不知道(不是静态的).

With IQueryable, you don't need Provider for this, it's enough to create the expression and then directly call OrderBy/OrderByDescending. The only problem is that OrderBy() is generic in the type of the sorting property, which you don't know (not statically).

您可以通过使用反射调用 OrderBy()来解决此问题.或者您可以使用 dynamic :

You can work around that by invoking OrderBy() using reflection. Or you can use 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完全使用它:

And you can use exactly the same with 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);
    }
}

这篇关于如何使用表达式树为PLINQ构建动态查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆