通常呢我们需要翻页的数据大多都是从数据库中取,翻页、筛选、排序啥的都是通过SQL语句由数据库帮我搞定,那么有些需求没有数据库呢?或者有些数据只存在于内存中不存到数据库呢?怎么实现内存里面的对象集合的通用翻页呢?好吧,好在.net framework 3.5 新增加的LINQ to Object里面提供非常多的扩展方法,让我们省去了很多Object集合的操作,如是乎就在想,能不能做一个像数据库一样的,能做一个通用的满足翻页、筛选、排序的方法呢?

为了防止有些网站乱爬这里插个声明,本文章版权归作者及博客园所有!链接:http://www.cnblogs.com/fanqie-liuxiao

一、准备

继续阅读需要必须了解的小知识点(大鸟跳过):

扩展方法:

简单的个人理解,就是允许在一些无法继承的、Final类一的些扩展。是不是有点儿像很早以前javascript里面的扩展那些个浏览器对象来的?(到最后搞的乱七八遭/偷笑)。

来个例子吧。

  1. public static class extendClass
  2. {
  3. // 比如,我要给List<gameProduct>这个泛型集合添加一个MyPrint方法。我们可以这样做,注意函数签名.
  4. public static String MyPrint(this IEnumerable<object> list)
  5. {
  6. String rt="";
  7. IEnumerator<object> eartor = list.GetEnumerator();// 获得枚举器
  8. rt += "{\n";
  9. while(eartor.MoveNext())
  10. {
  11. rt += eartor.Current.ToString()+",\n";
  12. }
  13. rt += "}";
  14. return rt;
  15. }
  16. }

调用:

  1. List<gameProduct> list = new List<gameProduct>();
  2. list.Add(new gameProduct(1, 101, 100));
  3. list.Add(new gameProduct(1, 102, 2));
  4. list.MyPrint();

lambda表达式:

简单的个人理解,一个方便函数回调的一种写法,省去繁琐的委托定义,实际就是其实是个(委托+匿名函数)的简化写法,为什么我们要这么写?因为写程序里面有一个很重要的概念就是Callback,实现低耦合。有没有经验用javascript做轮子的朋友一定是痛彻心扉,哈哈。

来个例子吧。

  1. List<gameProduct> list = new List<gameProduct>();
  2. list.Add(new gameProduct(1, 101, 100));
  3. list.Add(new gameProduct(1, 102, 2));
  4. list.Add(new gameProduct(1, 101, 50));
  5. list.Add(new gameProduct(2, 106, 13));
  6. list.Add(new gameProduct(2, 103, 18));
  7. list.Add(new gameProduct(5, 118, 9));
  8. var enum_1 = list.Select(g => g);
  9. // var enum_2 = list.Select(delegate(gameProduct g){return g;});// 这个就是g => g
  10. Console.WriteLine(enum_1.MyPrint()); // 看它返回的是什么,先来体验一下

好吧,鄙人新手。准备知识就先讲这么多,以上的个人理解如果说的不恰当之处还请谅解或者留言讨论,如果对您有一丝丝的帮助,烦请您点个赞。如果您觉得这非常之烂,请把赞当“踩”点一下,好歹请我知道哈。

二 、实现通用集合对象翻页

上面废话扯太多了,这里就直接上代码啦

  1. /// <summary>
  2. /// 内存对象翻页
  3. /// </summary>
  4. /// <typeparam name="table">实体类型</typeparam>
  5. /// <param name="pageIndex">当前页数</param>
  6. /// <param name="rowCount">每页的条数</param>
  7. /// <param name="listModel">实体集合</param>
  8. /// <param name="filterModel">筛选实体参数</param>
  9. /// <param name="pk">主键</param>
  10. /// <param name="order">排序字段</param>
  11. /// <returns>翻页数据</returns>
  12. public static object Pager<Ttable>(int pageIndex, int pageSize, List<Ttable> source, Ttable filterModel, String pk = "ID", String order = "ID")
  13. where Ttable : EntityObject
  14. {
  15. try
  16. {
  17. Func<Ttable, Boolean> filterItem = null; // 筛选回调函数指针
  18. Func<Ttable, int> orderItem = null; // 排序回调函数指针
  19. #region 处理筛选条件
  20. if (filterModel != null)
  21. {
  22. foreach (var item in filterModel.GetType().GetProperties()) // 遍历筛选条件
  23. {
  24. object pro = item.GetValue(filterModel, null);
  25. string proName = item.Name;
  26. if (pro != null)
  27. {
  28. if (pro.GetType() == typeof(int) && !proName.Equals(pk)) // 当过滤参数类型为int类型的时候,屏蔽主键
  29. {
  30. filterItem += new Func<Ttable, Boolean>(
  31. delegate(Ttable model)
  32. {
  33. object modelPro = item.GetValue(model, null);
  34. if (modelPro == pro)
  35. {
  36. return true;
  37. }
  38. return false;
  39. });
  40. }
  41. if (pro.GetType() == typeof(string) && !pro.ToString().Equals("")) // 当过滤参数为String类型的时候,屏蔽空字符串
  42. {
  43. filterItem += new Func<Ttable, Boolean>(
  44. delegate(Ttable model)
  45. {
  46. String modelPro = item.GetValue(model, null).ToString();
  47. if (modelPro.IndexOf(pro.ToString()) >= 0)
  48. {
  49. return true;
  50. }
  51. return false;
  52. });
  53. }
  54. // ...
  55. }
  56. if (proName.Equals(order)) // 排序判断回调
  57. {
  58. if (pro.GetType() == typeof(int)) // 只对Int类型数据进行排序判断
  59. {
  60. orderItem += new Func<Ttable, int>(
  61. delegate(Ttable model)
  62. {
  63. int modelPro = (int)item.GetValue(model, null);
  64. return modelPro;
  65. });
  66. }
  67. }
  68. }
  69. }
  70. var vList = source.Where(m =>
  71. {
  72. Boolean mrt = false;
  73. if (filterItem != null)
  74. {
  75. if (filterItem(m)) // 筛选数据判断,每一条数据都会判断一下,所以回调函数存在效率问题
  76. {
  77. mrt = true;
  78. }
  79. }
  80. else
  81. {
  82. mrt = true;
  83. }
  84. return mrt;
  85. }); // 筛选后数据集
  86. #endregion
  87. #region 求总数
  88. Int32 totalCount = vList.Count(); // 当前筛选条件的总条数
  89. if (totalCount <= (pageIndex - 1) * pageSize) // 当前页数没有记录
  90. {
  91. return new Models.PageModel() { TotalCount = 0, Data = new List<object>() };
  92. }
  93. #endregion
  94. #region 处理排序
  95. if (orderItem != null)
  96. {
  97. vList = vList.OrderBy(orderItem, new CompareIntegers());
  98. }
  99. #endregion
  100. #region 处理翻页
  101. vList = vList.Skip((pageIndex - 1) * pageSize).Take(pageSize);
  102. Models.PageModel pm = new Models.PageModel() { TotalCount = totalCount, Data = vList.ToList() };
  103. return pm;
  104. #endregion
  105. }
  106. catch { }
  107. return null;
  108. }
  109. // DESC
  110. public class CompareIntegers : IComparer<int>
  111. {
  112. public int Compare(int i1, int i2)
  113. {
  114. return i2 - i1;
  115. }
  116. }

声明一下哈,这样的写法是一定存在性能问题的,我们这里只讲功能实现哈,这里以学习为主。有啥好的建议或者意见呢,大可留言扇我。

调用实例:

  1. public JsonResult Pager_Json2(FormCollection fm)
  2. {
  3. object oRT = null;
  4. try
  5. {
  6. Int32 pageIndex = Int32.Parse(fm["page"]);
  7. Int32 pageSize = Int32.Parse(fm["rows"]);
  8. TB_Devices tb_model = JsonConvert.DeserializeObject<TB_Devices>(fm["ParamString"]);
  9. List<TB_Devices> listObject = TaskManager.Service.TaskService.Instance.GetDevice(-1);
  10. oRT = Helper.PagerHelper.Pager<TB_Devices>(pageIndex, pageSize, listObject, tb_model, "D_ID", "D_ID");
  11. }
  12. catch { }
  13. return Json(oRT, JsonRequestBehavior.AllowGet);
  14. }

好吧,写的有点儿累了,可能对实用价值并不大,看在我写了这么多代码的份子上,敬请的“赞”当“踩”。

C# ,通用内存集合对象分页、筛选(lambda那点事)的更多相关文章

  1. 基于.net的分布式系统限流组件 C# DataGridView绑定List对象时,利用BindingList来实现增删查改 .net中ThreadPool与Task的认识总结 C# 排序技术研究与对比 基于.net的通用内存缓存模型组件 Scala学习笔记:重要语法特性

    基于.net的分布式系统限流组件   在互联网应用中,流量洪峰是常有的事情.在应对流量洪峰时,通用的处理模式一般有排队.限流,这样可以非常直接有效的保护系统,防止系统被打爆.另外,通过限流技术手段,可 ...

  2. Objective-C之集合对象的内存管理

    *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...

  3. 记一则 Lambda内递归调用方法将集合对象转换成树形结构

    public dynamic GetDepartments(string labID) { List<int> usedIDs = new List<int>(); //缓存已 ...

  4. 转载---Java集合对象的深度复制与普通复制

    原博文:http://blog.csdn.net/qq_29329775/article/details/49516247 最近在做算法作业时出现了错误,原因是没有弄清楚java集合的深度复制和浅度复 ...

  5. java IO之 序列流 集合对象Properties 打印流 流对象

    序列流 也称为合并流. SequenceInputStream 序列流,对多个流进行合并. SequenceInputStream 表示其他输入流的逻辑串联.它从输入流的有序集合开始,并从 第一个输入 ...

  6. (转)java中对集合对象list的几种循环访问总结

    Java集合的Stack.Queue.Map的遍历   在集合操作中,常常离不开对集合的遍历,对集合遍历一般来说一个foreach就搞定了,但是,对于Stack.Queue.Map类型的遍历,还是有一 ...

  7. 《纵向切入ASP.NET 3.5控件和组件开发技术》笔记:高效率事件集合对象

    在之前讲的几个例子中,使用的是最普通的定义事件方法,比如KingTextBox中事件是这样定义的:/// <summary>/// 获得本书更多内容,请看:/// http://blog. ...

  8. java 多线程 线程安全及非线程安全的集合对象

    一.概念: 线程安全:就是当多线程访问时,采用了加锁的机制:即当一个线程访问该类的某个数据时,会对这个数据进行保护,其他线程不能对其访问,直到该线程读取完之后,其他线程才可以使用.防止出现数据不一致或 ...

  9. 《闲扯Redis十一》Redis 有序集合对象底层实现

    一.前言 Redis 提供了5种数据类型:String(字符串).Hash(哈希).List(列表).Set(集合).Zset(有序集合),理解每种数据类型的特点对于redis的开发和运维非常重要. ...

随机推荐

  1. VS Code 缩小

    一.问题描述 当我们在使用 Visual Studio Code 时,放大,我们可以使用 “ CTRL + ” 快捷键来实现.在使用 “ CRRL - ” 快捷键,缩小不了,我们怎么办? 二.解决方案 ...

  2. 从CGI到FastCGI到PHP-FPM

    从CGI到FastCGI到PHP-FPM 背景 笔者在学习这几个名词的时候,也是被百度到的相关文章迷惑.涉及到的主要名词包括 1. CGI协议 2. CGI脚本 3. PHP-CGI 4. FastC ...

  3. 【leetcode 3. 无重复字符的最长子串】解题报告

    思路:滑动窗口的思想 方法一:滑动窗口 int lengthOfLongestSubstring(string s) { /* 控制一个滑动窗口,窗口内的字符都是不重复的,通过set可以做到判断字符是 ...

  4. Wannafly summer camp Day2I(思维)

    #include<bits/stdc++.h>using namespace std;int a[1000007],b[1000007],c[1000007];int find_max(i ...

  5. (四)从输入URL到页面加载发生了什么

    一.从输入URL到页面加载发生了什么 1.在浏览器中输入URL 如:https://www.cnblogs.com/loveapple/ URL分成协议.地址.路径三部分 协议:http.https. ...

  6. Java Web之分页的实现(通用)

    一.用到的工具类的封装 为了实现代码的重用性,我们将经常用到的代码封装到工具类中,以便在任何地方都可以调用 1.获取路径工具 在jsp页面中,我们经常会向Servlet发送请求,并通过反射,实现通过传 ...

  7. Docker 快速安装&搭建 Ngnix 环境,并配置反向代理

    欢迎关注个人微信公众号: 小哈学Java, 文末分享阿里 P8 高级架构师吐血总结的 <Java 核心知识整理&面试.pdf>资源链接!! 个人网站: https://www.ex ...

  8. iOS通过SocketRocket实现websocket的即时聊天

    之前公司的即时聊天用的是常轮循,一直都觉得很不科学,最近后台说配置好了socket服务器,我高兴地准备用asyncsocket,但是告诉我要用websocket,基于HTML5的,HTML5中提出了一 ...

  9. HDU1729 Stone Game

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1729 思路:理解错题目了,以为SG模板直接套就行了.后来队友说了那个ci是不断变化的.那么每次可以放的石头 ...

  10. Github搭建个人博客

    Github的搭建博客真的是非常容易,所需的步骤只有三个:要完成自己的github.io博客网站,总共分三步:开通自己的github.io repo,选择一款Jekyll的主题,编写并发布博客.下面将 ...