C# ,通用内存集合对象分页、筛选(lambda那点事)
通常呢我们需要翻页的数据大多都是从数据库中取,翻页、筛选、排序啥的都是通过SQL语句由数据库帮我搞定,那么有些需求没有数据库呢?或者有些数据只存在于内存中不存到数据库呢?怎么实现内存里面的对象集合的通用翻页呢?好吧,好在.net framework 3.5 新增加的LINQ to Object里面提供非常多的扩展方法,让我们省去了很多Object集合的操作,如是乎就在想,能不能做一个像数据库一样的,能做一个通用的满足翻页、筛选、排序的方法呢?
为了防止有些网站乱爬这里插个声明,本文章版权归作者及博客园所有!链接:http://www.cnblogs.com/fanqie-liuxiao
一、准备
继续阅读需要必须了解的小知识点(大鸟跳过):
扩展方法:
简单的个人理解,就是允许在一些无法继承的、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();
lambda表达式:
简单的个人理解,一个方便函数回调的一种写法,省去繁琐的委托定义,实际就是其实是个(委托+匿名函数)的简化写法,为什么我们要这么写?因为写程序里面有一个很重要的概念就是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()); // 看它返回的是什么,先来体验一下
好吧,鄙人新手。准备知识就先讲这么多,以上的个人理解如果说的不恰当之处还请谅解或者留言讨论,如果对您有一丝丝的帮助,烦请您点个赞。如果您觉得这非常之烂,请把赞当“踩”点一下,好歹请我知道哈。
二 、实现通用集合对象翻页
上面废话扯太多了,这里就直接上代码啦
/// <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);
}
好吧,写的有点儿累了,可能对实用价值并不大,看在我写了这么多代码的份子上,敬请的“赞”当“踩”。
C# ,通用内存集合对象分页、筛选(lambda那点事)的更多相关文章
- 基于.net的分布式系统限流组件 C# DataGridView绑定List对象时,利用BindingList来实现增删查改 .net中ThreadPool与Task的认识总结 C# 排序技术研究与对比 基于.net的通用内存缓存模型组件 Scala学习笔记:重要语法特性
基于.net的分布式系统限流组件 在互联网应用中,流量洪峰是常有的事情.在应对流量洪峰时,通用的处理模式一般有排队.限流,这样可以非常直接有效的保护系统,防止系统被打爆.另外,通过限流技术手段,可 ...
- Objective-C之集合对象的内存管理
*:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...
- 记一则 Lambda内递归调用方法将集合对象转换成树形结构
public dynamic GetDepartments(string labID) { List<int> usedIDs = new List<int>(); //缓存已 ...
- 转载---Java集合对象的深度复制与普通复制
原博文:http://blog.csdn.net/qq_29329775/article/details/49516247 最近在做算法作业时出现了错误,原因是没有弄清楚java集合的深度复制和浅度复 ...
- java IO之 序列流 集合对象Properties 打印流 流对象
序列流 也称为合并流. SequenceInputStream 序列流,对多个流进行合并. SequenceInputStream 表示其他输入流的逻辑串联.它从输入流的有序集合开始,并从 第一个输入 ...
- (转)java中对集合对象list的几种循环访问总结
Java集合的Stack.Queue.Map的遍历 在集合操作中,常常离不开对集合的遍历,对集合遍历一般来说一个foreach就搞定了,但是,对于Stack.Queue.Map类型的遍历,还是有一 ...
- 《纵向切入ASP.NET 3.5控件和组件开发技术》笔记:高效率事件集合对象
在之前讲的几个例子中,使用的是最普通的定义事件方法,比如KingTextBox中事件是这样定义的:/// <summary>/// 获得本书更多内容,请看:/// http://blog. ...
- java 多线程 线程安全及非线程安全的集合对象
一.概念: 线程安全:就是当多线程访问时,采用了加锁的机制:即当一个线程访问该类的某个数据时,会对这个数据进行保护,其他线程不能对其访问,直到该线程读取完之后,其他线程才可以使用.防止出现数据不一致或 ...
- 《闲扯Redis十一》Redis 有序集合对象底层实现
一.前言 Redis 提供了5种数据类型:String(字符串).Hash(哈希).List(列表).Set(集合).Zset(有序集合),理解每种数据类型的特点对于redis的开发和运维非常重要. ...
随机推荐
- vue入门(一)----组件
由于工作需要,最近在写一些前端的东西.经过向开发经验丰富的前端工程师的请教之后,得出一个结论----2016年前端被玩坏了,其实对于我来说我并不是太了解这句话的深刻含义,只是觉得是不是因为前端技术突飞 ...
- Unity 分场景打包
分场景打包步骤:导入unity中AB包后 1: 指定场景 2: 指定abname 3: 指定objinabname 4: 协同 5: 委托 void string unity 先引入命名空间 ...
- SQLServer数据库权限设置--保障数据库安全
一.登陆界面引入 下图为SQL Server的登陆界面. 1)服务器名称:“.”代表本地计算机,选择下拉框,可以看见还有一个与本机机名相同的内容,也代表于本地服务器连接:要连接远程服务器的话,在此处填 ...
- libguestfs知识点
libguestfs 是一组 Linux 下的 C 语言的 API ,用来访问虚拟机的磁盘映像文件.其项目主页是http://libguestfs.org/ , 该工具包内包含的工具有virt-cat ...
- Linux中网卡相关命令以及SSH连接远程主机
ifconfig 命令 查看与配置网络状态命令 关闭与启动网卡 ifdown 网卡设备名 禁用该网卡设备 ifup 网卡设备名 启用该网卡设备 查询网络状态 netstat 选项 -t 列出TCP协议 ...
- lj的锁
lj的锁 Lj花很大力气设计了一个锁,有一天,lj用这个锁把lbn锁在了一个小房间里,准备把lbn啊掉,现在lbn要逃出这个房间,他需要解开这个锁.在平面上有n个钉子,第i个钉子的位置是(x[i],0 ...
- sys_guid()
create extension "uuid-ossp"; create or replace function sys_guid() returns uuid as $$sele ...
- SpringMVC 思想介绍
MVC 思想简介 博客园好像不支持发布markdown的时序图, 如果你会markdown并且不太熟悉Springmvc执行流程, 照着图在Markdown上面敲一遍执行流程,这是我经历过的最快的记忆 ...
- 任务计划cron
在linux中,任务计划分俩:未来时间只执行一次和周期性执行 at:未来时间只执行一次 -V 显示版本信息 -l: 列出指定队列中等待运行的作业:== atq -d: 删除指定的作业:== atrm ...
- 解决request中文乱码问题
因为request请求都是ISO-8859-1,而jsp页面是采用UTF-8编码,所以当传递的参数有中文时,页面会出现乱码,但是可以将取到的数据通过String的构造函数使用指定的编码类型重新构造一个 ...