一般呢咱們須要翻頁的數據大多都是從數據庫中取,翻頁、篩選、排序啥的都是經過SQL語句由數據庫幫我搞定,那麼有些需求沒有數據庫呢?或者有些數據只存在於內存中不存到數據庫呢?怎麼實現內存裏面的對象集合的通用翻頁呢?好吧,好在.net framework 3.5 新增長的LINQ to Object裏面提供很是多的擴展方法,讓咱們省去了不少Object集合的操做,如是乎就在想,能不能作一個像數據庫同樣的,能作一個通用的知足翻頁、篩選、排序的方法呢?javascript
爲了防止有些網站亂爬這裏插個聲明,本文章版權歸做者及博客園全部!連接:http://www.cnblogs.com/fanqie-liuxiaojava
繼續閱讀須要必須瞭解的小知識點(大鳥跳過):數據庫
簡單的我的理解,就是容許在一些沒法繼承的、Final類一的些擴展。是否是有點兒像很早之前javascript裏面的擴展那些個瀏覽器對象來的?(到最後搞的亂七八遭/偷笑)。瀏覽器
來個例子吧。函數
public static class extendClass { // 好比,我要給List<gameProduct>這個泛型集合添加一個MyPrint方法。咱們能夠這樣作,注意函數簽名. public static String MyPrint(this IEnumerable<object> list) { String rt=""; IEnumerator<object> eartor = list.GetEnumerator();// 得到枚舉器 rt += "{\n"; while(eartor.MoveNext()) { rt += eartor.Current.ToString()+",\n"; } rt += "}"; return rt; } }
調用:性能
List<gameProduct> list = new List<gameProduct>(); list.Add(new gameProduct(1, 101, 100)); list.Add(new gameProduct(1, 102, 2)); list.MyPrint();
簡單的我的理解,一個方便函數回調的一種寫法,省去繁瑣的委託定義,實際就是實際上是個(委託+匿名函數)的簡化寫法,爲何咱們要這麼寫?由於寫程序裏面有一個很重要的概念就是Callback,實現低耦合。有沒有經驗用javascript作輪子的朋友必定是痛徹心扉,哈哈。學習
來個例子吧。網站
List<gameProduct> list = new List<gameProduct>(); list.Add(new gameProduct(1, 101, 100)); list.Add(new gameProduct(1, 102, 2)); list.Add(new gameProduct(1, 101, 50)); list.Add(new gameProduct(2, 106, 13)); list.Add(new gameProduct(2, 103, 18)); list.Add(new gameProduct(5, 118, 9)); var enum_1 = list.Select(g => g); // var enum_2 = list.Select(delegate(gameProduct g){return g;});// 這個就是g => g Console.WriteLine(enum_1.MyPrint()); // 看它返回的是什麼,先來體驗一下
好吧,鄙人新手。準備知識就先講這麼多,以上的我的理解若是說的不恰當之處還請諒解或者留言討論,若是對您有一絲絲的幫助,煩請您點個贊。若是您以爲這很是之爛,請把贊當「踩」點一下,好歹請我知道哈。this
上面廢話扯太多了,這裏就直接上代碼啦.net
/// <summary> /// 內存對象翻頁 /// </summary> /// <typeparam name="table">實體類型</typeparam> /// <param name="pageIndex">當前頁數</param> /// <param name="rowCount">每頁的條數</param> /// <param name="listModel">實體集合</param> /// <param name="filterModel">篩選實體參數</param> /// <param name="pk">主鍵</param> /// <param name="order">排序字段</param> /// <returns>翻頁數據</returns> public static object Pager<Ttable>(int pageIndex, int pageSize, List<Ttable> source, Ttable filterModel, String pk = "ID", String order = "ID") where Ttable : EntityObject { try { Func<Ttable, Boolean> filterItem = null; // 篩選回調函數指針 Func<Ttable, int> orderItem = null; // 排序回調函數指針 #region 處理篩選條件 if (filterModel != null) { foreach (var item in filterModel.GetType().GetProperties()) // 遍歷篩選條件 { object pro = item.GetValue(filterModel, null); string proName = item.Name; if (pro != null) { if (pro.GetType() == typeof(int) && !proName.Equals(pk)) // 當過濾參數類型爲int類型的時候,屏蔽主鍵 { filterItem += new Func<Ttable, Boolean>( delegate(Ttable model) { object modelPro = item.GetValue(model, null); if (modelPro == pro) { return true; } return false; }); } if (pro.GetType() == typeof(string) && !pro.ToString().Equals("")) // 當過濾參數爲String類型的時候,屏蔽空字符串 { filterItem += new Func<Ttable, Boolean>( delegate(Ttable model) { String modelPro = item.GetValue(model, null).ToString(); if (modelPro.IndexOf(pro.ToString()) >= 0) { return true; } return false; }); } // ... } if (proName.Equals(order)) // 排序判斷回調 { if (pro.GetType() == typeof(int)) // 只對Int類型數據進行排序判斷 { orderItem += new Func<Ttable, int>( delegate(Ttable model) { int modelPro = (int)item.GetValue(model, null); return modelPro; }); } } } } var vList = source.Where(m => { Boolean mrt = false; if (filterItem != null) { if (filterItem(m)) // 篩選數據判斷,每一條數據都會判斷一下,因此回調函數存在效率問題 { mrt = true; } } else { mrt = true; } return mrt; }); // 篩選後數據集 #endregion #region 求總數 Int32 totalCount = vList.Count(); // 當前篩選條件的總條數 if (totalCount <= (pageIndex - 1) * pageSize) // 當前頁數沒有記錄 { return new Models.PageModel() { TotalCount = 0, Data = new List<object>() }; } #endregion #region 處理排序 if (orderItem != null) { vList = vList.OrderBy(orderItem, new CompareIntegers()); } #endregion #region 處理翻頁 vList = vList.Skip((pageIndex - 1) * pageSize).Take(pageSize); Models.PageModel pm = new Models.PageModel() { TotalCount = totalCount, Data = vList.ToList() }; return pm; #endregion } catch { } return null; } // DESC public class CompareIntegers : IComparer<int> { public int Compare(int i1, int i2) { return i2 - i1; } }
聲明一下哈,這樣的寫法是必定存在性能問題的,咱們這裏只講功能實現哈,這裏以學習爲主。有啥好的建議或者意見呢,大可留言扇我。
調用實例:
public JsonResult Pager_Json2(FormCollection fm) { object oRT = null; try { Int32 pageIndex = Int32.Parse(fm["page"]); Int32 pageSize = Int32.Parse(fm["rows"]); TB_Devices tb_model = JsonConvert.DeserializeObject<TB_Devices>(fm["ParamString"]); List<TB_Devices> listObject = TaskManager.Service.TaskService.Instance.GetDevice(-1); oRT = Helper.PagerHelper.Pager<TB_Devices>(pageIndex, pageSize, listObject, tb_model, "D_ID", "D_ID"); } catch { } return Json(oRT, JsonRequestBehavior.AllowGet); }
好吧,寫的有點兒累了,可能對實用價值並不大,看在我寫了這麼多代碼的份子上,敬請的「贊」當「踩」。