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 += "{
";
        while(eartor.MoveNext())
        {
            rt += eartor.Current.ToString()+",
";
        }
        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);
}

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

博文作者:番茄炒西红柿
博文出处:http://www.cnblogs.com/fanqie-liuxiao/
本文版权归作者和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作! 如果阅读了本文章,觉得有帮助,您可以为我的博文点击“推荐一下”!
原文地址:https://www.cnblogs.com/fanqie-liuxiao/p/5796128.html