NET 基于反射,泛型排序扩展类

ReflectionOrderExtend.cs

复制代码
   /// <summary>
    /// 泛型排序扩展类:运行时一个泛型一个实例
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class ReflectionOrderExtend<T>
    {
        /// <summary>
        /// Key:Expression_PropertyTypeName_PropertyFieldName
        /// Value:表达式[x => x.Name]
        /// </summary>
        private readonly static Dictionary<string, dynamic> ExpressionDirctionary = new Dictionary<string, dynamic>();

        /// <summary>
        /// 静态访问类只会访问一次
        /// </summary>
        static ReflectionOrderExtend()
        {

        }

        /// <summary>
        /// 每次New都会访问
        /// </summary>
        public ReflectionOrderExtend()
        {

        }

        /// <summary>
        /// 自定义排序
        /// </summary>
        /// <param name="dbModelList"></param>
        /// <param name="orderbyList"></param>
        /// <returns></returns>
        public static IEnumerable<T> CustOrder(IEnumerable<T> dbModelList, List<string> orderbyList)
        {
            if (orderbyList.IsNullOrEmpty()) return dbModelList;

            var type = typeof(T);
            var count = orderbyList.Count();
            IOrderedEnumerable<T> orderList = null;
            // 1.定义lamada的参数,型如我们常写的“x=>”
            ParameterExpression m_Parameter = Expression.Parameter(type, "x");

            for (int i = 0; i < count; i++)
            {
                var orderBy = orderbyList[i].Split(' ');

                // 排序字段
                var itemFieldName = orderBy[0];
                // 严格区分大小写
                var itemProperInfo = type.GetProperty(itemFieldName);
                if (itemProperInfo == null) continue;
                var itemType = itemProperInfo.PropertyType;

                // 排序方式,默认Asc:Asc | Desc
                var itemSort = orderBy.Length > 1 ? orderBy[1] : string.Empty;
                // 动态构建表达式
                var lamada = BuilderLambda(type, m_Parameter, itemFieldName);

                switch (itemSort?.ToLower())
                {
                    case "desc":
                        //if (i == 0) orderList = dbModelList.OrderByDescending(x => lamada);
                        //else orderList = orderList.ThenByDescending(x => lamada);
                        if (i == 0) orderList = dbModelList.OrderByDescending(x => lamada(x));
                        else orderList = orderList.ThenByDescending(x => lamada(x));
                        break;
                    case "":
                    case "asc":
                    default:
                        //if (i == 0) orderList = dbModelList.OrderBy(x => lamada);
                        //else orderList = orderList.ThenBy(x => lamada);
                        if (i == 0) orderList = dbModelList.OrderBy(x => lamada(x));
                        else orderList = orderList.ThenBy(x => lamada(x));
                        break;
                }
            }
            var newDbModelList = orderList.IsNullOrEmpty() ? dbModelList : orderList.ToList();
            return newDbModelList;
        }

        /// <summary>
        /// 动态构建表达式
        /// </summary>
        /// <param name="type"></param>
        /// <param name="m_Parameter"></param>
        /// <param name="itemFieldName"></param>
        /// <returns></returns>
        private static dynamic BuilderLambda(System.Type type, ParameterExpression m_Parameter, string itemFieldName)
        {
            // 缓存Key
            var itemKey = $"Expression_{type.Name}_{itemFieldName}";
            dynamic lamada;
            if (ExpressionDirctionary.ContainsKey(itemKey))
            {
                lamada = ExpressionDirctionary[itemKey];
            }
            else
            {
                // 2.定义要使用lamada的属性成员(比如我们这里要对DTO_ORDER对象的ORDER_NO属性做筛选)
                MemberExpression member = Expression.PropertyOrField(m_Parameter, itemFieldName);

                // 3.转换为Expression表达式   x => x.XXX
                dynamic exprelamada = Expression.Lambda(member, m_Parameter);

                //5.将Expression表达式转换为Func委托,用于Where里面的参数
                lamada = exprelamada.Compile();
                ExpressionDirctionary.Add(itemKey, lamada);
            }

            return lamada;
        }
    }
View Code
复制代码

 

posted @   Robot-Blog  阅读(38)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示