让 Linq 支持动态列名排序

        /// Queryable的内部实现
        /// 做了部分调整
        public static IOrderedQueryable<TSource> OrderBy<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
        {
            if (source == null) throw new Exception("source");
            if (keySelector == null) throw new Exception("keySelector");

            //使用提供程序的的CreateQuery,来建立表达公树
            //建立后的表达式数在调用Provider.Execute时被正式解析成以及执行
            return (IOrderedQueryable<TSource>)source.Provider.CreateQuery<TSource>(
                  Expression.Call(
                   null,
                   //下面句返回的OrderBy<TSource,TKey>方法的MethodInfo
                   ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new Type[] { typeof(TSource), typeof(TKey) }),
                   //关键是Expression.Quote(keySelector)
                   //需要使用自己LambdaExpression来替换KeySelector
                   new Expression[] { source.Expression, Expression.Quote(keySelector) }
                  )
                );
        }

        /// 由于本质Linq To EF 支持OrderBy 等
        /// 所以只要模拟个keySelector后,将剩余的工作交还给Linq To EF Provider来处理
        public static IOrderedQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> source, string propertyStr) where TEntity : class
        {

            //以下四句用来购建立 c=>c.propertyStr 的Expression
            ParameterExpression param = Expression.Parameter(typeof(TEntity), "c");
            PropertyInfo property = typeof(TEntity).GetProperty(propertyStr);
            Expression propertyAccessExpression = Expression.MakeMemberAccess(param, property);
            LambdaExpression le = Expression.Lambda(propertyAccessExpression, param);

            Type type = typeof(TEntity);
            //Expression.Call跟上面的一样,这里采用重载形式,上面的GetCurrentMethod结果也是"OrderBy"
            //Expression.Call方法会利用typeof(Queryable),"OrderBy",new Type[]{type,property.PropertyType}三个参数
            //合成跟MethodInfo等同的信息
            MethodCallExpression resultExp = Expression.Call(typeof(Queryable), "OrderBy", new Type[] { type, property.PropertyType }, source.Expression, Expression.Quote(le));
            return (IOrderedQueryable<TEntity>)source.Provider.CreateQuery<TEntity>(resultExp);
        }

下面的参考地址中可以找到完整实现

//===================

参考下文:

http://www.cnblogs.com/xxfss2/archive/2010/12/13/1905023.html

http://www.cnblogs.com/Terrylee/archive/2008/08/01/custom-linq-provider-part-1-expression-tree.html

http://www.cnblogs.com/Terrylee/archive/2008/08/25/custom-linq-provider-part-2-IQueryable-IQueryProvider.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值