Entity Framework 多条件排序与分页的实现

项目过程中遇到需要对数据源进行多条件排序的情况,

开始觉得很简单,分分钟搞定,当时的逻辑大概是将排序条件以及是否倒序写入Dictionary中,在方法中遍历此Dictionary进行排序(下面的方法附带了分页,其实觉得耦合度太高,感觉还是都分开比较好)

 

 

public IQueryable<T> GetListByPage<S>(int pageSize, int pageIndex, out int pageCount, Expression<Func<T, bool>> predicate, Dictionary<Expression<Func<T, S>>, bool> orderbyCondition = null)
{
var temp = MyContext.Set<T>().Where(predicate);
pageCount = temp.Count();
if (orderbyCondition != null && orderbyCondition.Count > 0)
{
int index = 1;
foreach (var condition in orderbyCondition)
{
if (index == 1)
{
temp = condition.Value ? temp.OrderBy<T, S>(condition.Key) : temp.OrderByDescending<T, S>(condition.Key);
index++;
}
else
{
temp = condition.Value ? (temp as IOrderedQueryable<T>).ThenBy(condition.Key) : (temp as IOrderedQueryable<T>).ThenByDescending(condition.Key);
}
 
}
}
temp = temp.Skip<T>((pageIndex - 1) * pageSize)
.Take<T>(pageSize);
return temp.AsQueryable();
}

 

满怀希望地打开了页面,看到了很骨感的现实-"出错了",分析了一下 原因是在传递Dictionary参数的时候,里面写入的泛型返回类型不同;

按照时间排序 返回类型就是Datetime ,按照序号排序 返回类型就是int 之后试着在传参的时候这么写

Dictionary<object,bool> conditionDic, 但实际执行的时候依然不行, EF必须指定返回类型.

为了不在每个entity的BLL都要改一遍, 我决定写一个底层的方法, 在网上查了一些资料,参考了其中一位大神的思路http://www.cnblogs.com/hun_dan/archive/2012/10/23/2735255.html

,完成了这个需求.

过程中的需要注意的地方大概有如下几点:

  1. 排序条件返回类型不一致
  2. 正序倒序不确定
  3. OrderBy和ThenBy(头次排序及后续排序)

 

大概思路:

定义一个接口,重写两个方法orderby和thenby, 用类型ExpressionCondition实现这个接口, 此外类型成员还有condition以及isDesc,并在构造函数中赋初值.

声明主调用函数,将排序条件作为数组ExpressionCondition[]传递;以下是实现代码

BaseEntity 为实体基类,其余实体只需要继承基类即可调用此方法

Interface:

 
   public interface IOrderByMultiCondition<T>
        where T : BaseEntity
    {
        IOrderedQueryable<T> ApplyOrderBy(IQueryable<T> query);
        IOrderedQueryable<T> ApplyThenBy(IOrderedQueryable<T> query);
    }

 

Class

 public class OrderByMultiCondition<T, R> : IOrderByMultiCondition<T>
        where T : BaseEntity
    {
        Expression<Func<T, R>> _expressionn;
        bool _isDesc;

        public OrderByMultiCondition(Expression<Func<T, R>> expression, bool IsDesc = false)
        {
            _expressionn = expression;
            _isDesc = IsDesc;
        }

        public IOrderedQueryable<T> ApplyOrderBy(IQueryable<T> query)
        {
            if (_isDesc)
            {
                return query.OrderByDescending(_expressionn);
            }
            else
                return query.OrderBy(_expressionn);
        }

        public IOrderedQueryable<T> ApplyThenBy(IOrderedQueryable<T> query)
        {
            if (_isDesc)
            {
                return query.ThenByDescending(_expressionn);
            }
            else
                return query.ThenBy(_expressionn);
        }

    }

 

Repository

public IQueryable<T> GetListByPage(int pageSize, int pageIndex, out int pageCount, Expression<Func<T, bool>> predicate, params IOrderByMultiCondition<T>[] orderByExpressions)
        {
            var temp = MyContext.Set<T>().Where(predicate);
            pageCount = temp.Count();
            if (orderByExpressions != null)
            {
                IOrderedQueryable<T> afterFirstSort = null;
                foreach (var expression in orderByExpressions)
                {
                    if (afterFirstSort == null)
                    {
                        afterFirstSort = expression.ApplyOrderBy(temp);
                    }
                    else
                        afterFirstSort = expression.ApplyThenBy(afterFirstSort);

                }
                temp = afterFirstSort;
            }
            temp = temp.Skip<T>((pageIndex - 1) * pageSize)
                .Take<T>(pageSize);
            return temp.AsQueryable();
        }

 

转载于:https://www.cnblogs.com/shsmin1992/p/3890558.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值