標籤:des style blog http color os io 資料
項目過程中遇到需要對資料來源進行多條件排序的情況,
開始覺得很簡單,分分鐘搞定,當時的邏輯大概是將排序條件以及是否倒序寫入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
,完成了這個需求.
過程中的需要注意的地方大概有如下幾點:
- 排序條件傳回型別不一致
- 正序倒序不確定
- 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(); }