排序使用Linq.Ex pressions.Ex pression [英] Sort using Linq.Expressions.Expression

查看:178
本文介绍了排序使用Linq.Ex pressions.Ex pression的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写这篇code表示排序的的IQueryable< T> [化列 sortColumn 。我想它延伸,使得具有列的值项出生日期等于 DateTime.Today 会在排序先放入,但我就是无法找到或想到如何做这项工作。

 公共静态的IQueryable< T> OrderByField< T>(这IQueryable的< T> Q,串sortColumn,布尔ASC)
{
    VAR参数=前pression.Parameter(typeof运算(T),P);

    VAR道具=前pression.Property(参数,sortColumn);

    VAR EXP =前pression.Lambda(道具,参数);

    字符串的方法=递增? 排序依据:OrderByDescending;

    键入[]类型=新的[] {q.ElementType,exp.Body.Type};

    VAR MCE =前pression.Call(typeof运算(可查询),方法,种类,q.Ex pression,EXP​​);

    返回q.Provider.CreateQuery< T>(MCE);
}
 

解决方案

见的手柄GridView.OnSorting(),并创建动态排序使用LINQ EX pression

 公共静态类SORTEX pressionBuilder< T>
{
    私有静态的IDictionary< SortDirection,ISortEx pression>方向=新字典< SortDirection,ISortEx pression>
    {
        {SortDirection.Ascending,新OrderByAscendingSortEx pression()},
        {SortDirection.Descending,新OrderByDescendingSortEx pression()}
    };

    接口ISortEx pression
    {
        FUNC< IEnumerable的< T&GT ;,函数功能< T,对象>中的IEnumerable< T>> GETEX pression();
    }

    类OrderByAscendingSortEx pression:ISortEx pression
    {
        公共函数功能:LT; IEnumerable的< T&GT ;,函数功能< T,对象>中的IEnumerable< T>> GETEX pression()
        {
            返程(C,F)=> c.OrderBy(F);
        }
    }

    类OrderByDescendingSortEx pression:ISortEx pression
    {
        公共函数功能:LT; IEnumerable的< T&GT ;,函数功能< T,对象>中的IEnumerable< T>> GETEX pression()
        {
            返程(C,F)=> c.OrderByDescending(F);
        }
    }

    公共静态函数功能:LT; IEnumerable的< T&GT ;,函数功能< T,对象>中的IEnumerable< T>> CreateEx pression(SortDirection方向)
    {
        返回的方向[方向] .GetEx pression();
    }
}

公共静态的IEnumerable< T>排序依据< T>(这IEnumerable的< T>收集,串COLUMNNAME,SortDirection方向)
{
    ParameterEx pression参数=前pression.Parameter(typeof运算(T),X); // x
    防爆pression属性=前pression.Property(参数,COLUMNNAME); // x.ColumnName
    FUNC< T,对象> FUNC =前pression.Lambda< Func键< T,对象>>(// X => x.ColumnName
       防爆pression.Convert(出pression.Property(参数,COLUMNNAME)
       typeof运算(对象)),参数
    ).Compile();

    FUNC< IEnumerable的< T&GT ;,函数功能< T,对象>中的IEnumerable< T>> EX pression = SORTEX pressionBuilder< T> .CreateEx pression(方向);
    IEnumerable的< T>分拣= EX pression(收集,FUNC);
    返回排序;
}
 

和从底部链接:

I wrote this code that sorts an IQueryable<T> by the column sortColumn. I would like to extend it so that the entries that have the value of the column BirthDate equal to DateTime.Today would be placed first in the sort, but I just can't find or think of how to do the job.

public static IQueryable<T> OrderByField<T>(this IQueryable<T> q, string sortColumn, bool asc)
{
    var param = Expression.Parameter(typeof(T), "p");

    var prop = Expression.Property(param, sortColumn);

    var exp = Expression.Lambda(prop, param);

    string method = asc ? "OrderBy" : "OrderByDescending";

    Type[] types = new[] { q.ElementType, exp.Body.Type };

    var mce = Expression.Call(typeof(Queryable), method, types, q.Expression, exp);

    return q.Provider.CreateQuery<T>(mce);
}

解决方案

See Handle GridView.OnSorting() and create sorting expression dynamically using LINQ

public static class SortExpressionBuilder<T>
{
    private static IDictionary<SortDirection, ISortExpression> directions =  new Dictionary<SortDirection, ISortExpression>
    {
        { SortDirection.Ascending, new OrderByAscendingSortExpression() },
        { SortDirection.Descending, new OrderByDescendingSortExpression() }
    };

    interface ISortExpression
    {
        Func<IEnumerable<T>, Func<T, object>, IEnumerable<T>> GetExpression();
    }

    class OrderByAscendingSortExpression : ISortExpression
    {
        public Func<IEnumerable<T>, Func<T, object>, IEnumerable<T>> GetExpression()
        {
            return (c, f) => c.OrderBy(f);
        }
    }

    class OrderByDescendingSortExpression : ISortExpression
    {
        public Func<IEnumerable<T>, Func<T, object>, IEnumerable<T>> GetExpression()
        {
            return (c, f) => c.OrderByDescending(f);
        }
    }

    public static Func<IEnumerable<T>, Func<T, object>, IEnumerable<T>> CreateExpression(SortDirection direction)
    {
        return directions[direction].GetExpression();
    }
}

public static IEnumerable<T> OrderBy<T>(this IEnumerable<T> collection, string columnName, SortDirection direction)
{
    ParameterExpression param = Expression.Parameter(typeof(T), "x"); // x
    Expression property = Expression.Property(param, columnName);     // x.ColumnName
    Func<T, object> func = Expression.Lambda<Func<T, object>>(        // x => x.ColumnName
       Expression.Convert(Expression.Property(param, columnName), 
       typeof(object)), param
    ).Compile();

    Func<IEnumerable<T>, Func<T, object>, IEnumerable<T>> expression = SortExpressionBuilder<T>.CreateExpression(direction);
    IEnumerable<T> sorted = expression(collection, func);
    return sorted;
}

And links from the bottom:

这篇关于排序使用Linq.Ex pressions.Ex pression的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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