zoukankan      html  css  js  c++  java
  • 让Linq的OrderBy支持动态字段

    使用linq的OrderBy,如果明确知道是哪个字段,当然很容易:

     IQueryable<User> userQuery = ...;
     userQuery.OrderBy(u => u.Code)

    但假如我们想写一个通用方法,预先并不知道要用哪个字段排序呢?

    在网上寻寻觅觅,有许多国内的博客互相抄袭,信誓旦旦,但其实那些代码都运行不了。

    还是老外的好使:
    http://www.4byte.cn/question/33782/dynamic-orderby-using-linq-dynamic.html

    我拿来修改了一下,可以用。主要思想是扩展Queryable。但里面的东西有许多我都看不懂。

        public static class QueryableExtension
        {
            public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> query, string propertyName)
            {
                return _OrderBy<T>(query, propertyName, false);
            }
            public static IOrderedQueryable<T> OrderByDescending<T>(this IQueryable<T> query, string propertyName)
            {
                return _OrderBy<T>(query, propertyName, true);
            }
    
            static IOrderedQueryable<T> _OrderBy<T>(IQueryable<T> query, string propertyName,bool isDesc)
            {
                string methodname = (isDesc) ? "OrderByDescendingInternal" : "OrderByInternal";
    
                var memberProp = typeof(T).GetProperty(propertyName);
    
                var method = typeof(QueryableExtension).GetMethod(methodname)
                                           .MakeGenericMethod(typeof(T), memberProp.PropertyType);
    
                return (IOrderedQueryable<T>)method.Invoke(null, new object[] { query, memberProp });
            }
            public static IOrderedQueryable<T> OrderByInternal<T, TProp>(IQueryable<T> query, PropertyInfo memberProperty)
            {//public
                return query.OrderBy(_GetLamba<T, TProp>(memberProperty));
            }
            public static IOrderedQueryable<T> OrderByDescendingInternal<T, TProp>(IQueryable<T> query, PropertyInfo memberProperty)
            {//public
                return query.OrderByDescending(_GetLamba<T, TProp>(memberProperty));
            }
            static Expression<Func<T, TProp>> _GetLamba<T, TProp>(PropertyInfo memberProperty)
            {
                if (memberProperty.PropertyType != typeof(TProp)) throw new Exception();
    
                var thisArg = Expression.Parameter(typeof(T));
                var lamba = Expression.Lambda<Func<T, TProp>>(Expression.Property(thisArg, memberProperty), thisArg);
    
                return lamba;
            }
        }

    调用:

    IQueryable<User> userQuery = ...;
    //正序
    userQuery = userQuery.OrderBy("Code");
    //降序
    userQuery = userQuery.OrderByDescending("Code");
  • 相关阅读:
    编译并使用Lua语言
    C#中使用DLL文件
    将Unity3D游戏移植到Android平台上
    Unity3D知识点
    清下书柜,工作书,旧书,正版书,个人学习过的书asp,net,delphi,java,flex,actionscript,vb...
    使用ABP打造SAAS系统(2)——前端框架选择
    使用ABP打造SAAS系统(1)——环境准备
    延迟实例单例模式注意点
    jvm指令解释i = i++ + i++ + i++ + ++i;等于多少
    MYSQL增加库表权限
  • 原文地址:https://www.cnblogs.com/leftfist/p/6808785.html
Copyright © 2011-2022 走看看