通常呢我們需要翻頁的數據大多都是從數據庫中取,翻頁、篩選、排序啥的都是通過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);
}
好吧,寫的有點兒累了,可能對實用價值並不大,看在我寫了這么多代碼的份子上,敬請的“贊”當“踩”。