眾所周知,asp.net自帶的GridView在自帶分頁方面設計得很2,因為它是假分頁,即內存分頁。而且它不智能支持強大的Iqueryable。
但這表明微軟忽略了現實中的分頁需求嗎?答案應該不是,我想也不是。
那么,通過什么方式可以達到真分頁的效果呢?使用Asp.Net自帶的3種DataSource(objectdatasource, entitydatasource, linqdatasource)。 三種datasource各有所長。
但這樣做還是有些麻煩呀……
朋友有一個項目,之前數據少,沒有考慮過假分頁帶來的隱患,現在項目也做大了,數據也大了,問題也出來了,怎么辦可以實現最少改動呢?廢話不多說,直接上代碼:
1 自定義一個PageGridView
using System;using System.Collections;using System.Collections.Generic;using System.Data;using System.Linq;using System.Web;using System.Web.UI;using System.Web.UI.WebControls;using System.Reflection;namespace DGVTest{ public class PagingGridView : GridView { public PagingGridView() { } PRivate IQueryable querableData; public override Object DataSource { get { return base.DataSource; } set { if (value is IQueryable) { querableData = (IQueryable)value; ObjectDataSource ods = new ObjectDataSource(); ods.ID = "ods_" + this.ID; ods.EnablePaging = this.AllowPaging; // This must be the full name of the class ods.TypeName = "DGVTest.IQueryableAdapter"; ods.SelectMethod = "GetData"; ods.SelectCountMethod = "GetCount"; ods.StartRowIndexParameterName = "startRowIndex"; ods.MaximumRowsParameterName = "pageSize"; ods.EnableViewState = false; ods.ObjectCreating += (o,e)=> e.ObjectInstance = new IQueryableAdapter(querableData); base.DataSource = ods; if (AllowPaging) { PageIndexChanging += (o, gpe) => { PageIndex = gpe.NewPageIndex; DataBind(); }; } if (AllowSorting) { //---if want to implement sorting... } } else { base.DataSource = value; } } } } public class IQueryableAdapter { private IQueryable _data; private int _totalCount; public IQueryableAdapter(IQueryable data) { _data = data; _totalCount = (int)GetExtMethod("Count", _data ).Invoke(null, new object[] { _data }); } public object GetData() { return _data; } public int GetCount() { return _totalCount; } public object GetData(int startRowIndex, int pageSize) { var enumResult = GetExtMethod("Skip", _data).Invoke(null, new object[] { _data, startRowIndex }); return GetExtMethod("Take", _data ).Invoke(null, new object[] { enumResult, pageSize }); } private MethodInfo GetExtMethod(string methodName,object obj ) { var genType = obj.GetType().GetGenericArguments()[0]; return typeof(System.Linq.Queryable) .GetMethods(BindingFlags.Public | BindingFlags.Static) .First(m => m.Name == methodName) .MakeGenericMethod(genType); } } }2 把這個新的GridView引入原項目
一般的做法是在頁面上添加引用符:
<%@ Register Assembly="DGVTest" Namespace="DGVTest" TagPrefix="juyee" %>
然后把原GridView的前綴改了:
<juyee:PagingGridView ID="GridView1" runat="server" AllowPaging="True" AllowSorting="True"></juyee:PagingGridView>
但每個頁面都加引用命令,還是很麻煩的。這可以通過在config解決:
<system.web> <pages> <controls> <add tagPrefix="juyee" namespace="DGVTest" assembly="DGVTest" /> </controls> </pages> </system.web>
有了這個,就不用每個頁面加引用命令啦。至于替換gridview的聲明嘛,可以用ctrl+F。
3 Code-Behind
現在可以直接把IQueryable類型的對象做為新View的數據源啦。值得一提的是,一定要orderby一下喲,不然執行IQueryable.Skip時會報錯。
var ds= from t in new testdbEntities().People orderby t.Name select t; GridView1.DataSource =ds; GridView1.DataBind();
至此問題解決~趕快試試吧。

新聞熱點
疑難解答