C# OrderBy 扩展

public enum OrderByStatus
    {
        ASC,
        DESC
    }

    public static class OrderByHelper
    {
        public static IOrderedQueryable<T> OrderIf<T, TKey>(this IQueryable<T> source, Expression<Func<T, TKey>> order, OrderByStatus status, bool isEnable)
        {
            IOrderedQueryable<T> result = null;
            if (source != null && order != null)
            {
                if (isEnable)
                {
                    //已有OrderBy
                    if (source.ContainsOrderBy())
                    {
                        if (status == OrderByStatus.ASC)
                            result = (source as IOrderedQueryable<T>).ThenBy(order);
                        else
                            result = (source as IOrderedQueryable<T>).ThenByDescending(order);
                    }
                    else //未有 OrderBy
                    {
                        if (status == OrderByStatus.ASC)
                            result = source.OrderBy(order);
                        else
                            result = source.OrderByDescending(order);
                    }
                }
                else result = (source as IOrderedQueryable<T>);
            }
            return result;
        }

        /// <summary>
        /// 判断里面是否已经调用过 OrderBy、OrderByDescending 这两个函数否,
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source"></param>
        /// <returns></returns>
        public static bool ContainsOrderBy<T>(this IQueryable<T> source)
        {
            bool result = false;


            var expression = source.Expression;

            if (expression.NodeType == ExpressionType.Call)
            {
                result = FindIOrderedQueryable(expression as MethodCallExpression);
            }

            return result;
        }

        /// <summary>
        /// 递归子项找到 OrderBy、OrderByDescending 这两个函数的调用,
        /// 其中一个子项有,就返回 True,都没有的话,就返回 False
        /// </summary>
        /// <param name="Expression"></param>
        /// <returns></returns>
        private static bool FindIOrderedQueryable(MethodCallExpression Expression)
        {
            bool result = false;

            if (Expression.Method.Name == "OrderBy" || Expression.Method.Name == "OrderByDescending")
            {
                result = true;
            }
            else
            {
                foreach (var item in Expression.Arguments)
                {
                    if (item.NodeType == ExpressionType.Call)
                    {
                        result = FindIOrderedQueryable(item as MethodCallExpression);
                        if (result) break;
                    }
                }
            }

            return result;
        }
    }


核心代码其实是 FindIOrderedQueryable 这个函数,靠这货找出表达式中是否有调用过 OrderBy 或者 OrderByDescending 函数。

然后扩展函数根据这个结果来判断,现在给 IQueryable 加上的函数是 OrderBy 还是 ThenBy,

以后再也不用为往 IQueryable 后边加上 OrderBy 还是 ThenBy 操心了,一直加 OrderIf 扩展函数就可以,扩展函数自动判断是加入哪个函数。

以下是调用的示例:

class Program
    {
        static void Main(string[] args)
        {
            List<MyModel> list = new List<MyModel>();

            for (int i = 0; i < 20; i++)
            {
                list.Add(new MyModel()
                {
                    CreatedAt = DateTime.Now,
                    ID = i + 1,
                    OrderNumber = i,
                    Name = Char.ConvertFromUtf32(i)
                });
            }

            var query = list.AsQueryable();
            query = query.Where(s => !string.IsNullOrEmpty(s.Name))
                .Where(s => !string.IsNullOrEmpty(s.Name))
                .Where(s => !string.IsNullOrEmpty(s.Name))
                .Where(s => !string.IsNullOrEmpty(s.Name))
                .Where(s => !string.IsNullOrEmpty(s.Name))
                .Where(s => !string.IsNullOrEmpty(s.Name))
                .Where(s => !string.IsNullOrEmpty(s.Name))
                .Where(s => !string.IsNullOrEmpty(s.Name))
                .Where(s => !string.IsNullOrEmpty(s.Name))
                .Where(s => !string.IsNullOrEmpty(s.Name))
                .Where(s => !string.IsNullOrEmpty(s.Name))
                .Where(s => !string.IsNullOrEmpty(s.Name))
                .Where(s => !string.IsNullOrEmpty(s.Name))
                .Where(s => !string.IsNullOrEmpty(s.Name))
                .Where(s => !string.IsNullOrEmpty(s.Name))
                .Where(s => !string.IsNullOrEmpty(s.Name))
                .Where(s => !string.IsNullOrEmpty(s.Name))
                .Where(s => !string.IsNullOrEmpty(s.Name))
                .Where(s => !string.IsNullOrEmpty(s.Name))
                .Where(s => !string.IsNullOrEmpty(s.Name))
                .Where(s => !string.IsNullOrEmpty(s.Name))
                .Where(s => !string.IsNullOrEmpty(s.Name))
                .Where(s => !string.IsNullOrEmpty(s.Name))
                .Where(s => !string.IsNullOrEmpty(s.Name))
                .Where(s => !string.IsNullOrEmpty(s.Name))
                .Where(s => !string.IsNullOrEmpty(s.Name));

            query = query
                .OrderIf(s => s.OrderNumber, OrderByStatus.DESC, true)
                .OrderIf(s => s.CreatedAt, OrderByStatus.ASC, true);

            query = query.Where(s => s.CreatedAt.HasValue);

            Console.WriteLine(query.ContainsOrderBy());
            Console.ReadLine();
        }
    }

    public class MyModel
    {
        [Key]
        public long ID { get; set; }
        public string Name { get; set; }
        public DateTime? CreatedAt { get; set; }
        public int? OrderNumber { get; set; }
    }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值