[小技巧]让你的GridView支持IQueryable,并自动实现真分页

众所周知,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 paging...
                    }
                }
                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();

至此问题解决~赶快试试吧。

时间: 2024-10-11 06:18:15

[小技巧]让你的GridView支持IQueryable,并自动实现真分页的相关文章

【Android小技巧】通过gradle给module中资源文件自动加上前缀

问题: 经常遇到不同的module,资源同名的问题,为了解决这种问题,可以给各个module的资源添加不同的前缀,gradle脚本配置如下: android { compileSdkVersion rootProject.ext.android.compileSdkVersion buildToolsVersion rootProject.ext.android.buildToolsVersion defaultConfig { minSdkVersion rootProject.ext.and

Linux的95个小技巧

Linux的95个小技巧 by WEB全栈工程师 on 2012 年 03 月 27 日 这里总结了Linux使用中的一些小技巧 1.实现RedHat非正常关机的自动磁盘修复 先登录到服务器,然后在/etc/sysconfig里增加一个文件autofsck,内容如下:AUTOFSCK_DEF_CHECK=yesPROMPT=yes 2.改变文件或目录之最后修改时间(变为当前时间)执行格式:touch name ( name 可为文件或目录名称.) 3.如何设置login后欢迎信息 修改/etc/

MVC 基架不支持 Entity Framework 6 或更高版本 即 NuGet的几个小技巧

MVC 基架不支持 Entity Framework 6 或更高版本.有关详细信息,请访问 http://go.microsoft.com/fwlink/?LinkId=276833. 原因:mvc版本过低,ef版本过高 解决方法:1.从NuGet 卸载 ef 6.1 工具- 库程序包管理器 - 程序包管理控制台 输入PM> Uninstall-Package EntityFramework –Version 6.1.3 -Force 2.修改原语句 Install-Package <程序包名

实战基础技能(07)--------DEV控件的Gridview小技巧总结

1.设置Gridview控件的某列不可编辑 this.gridData.gridView1.Columns["change_date"].OptionsColumn.AllowEdit = false; 字段:change_date是数据库中字段,是绑定到gridview上的. 2.设置Gridview控件整体不可编辑 this.gridData.IsEnableEdit = false; 3.设置Gridview控件,列头不可排序 this.gridDataDetail.gridVi

Android开发的那些坑和小技巧

1.android:clipToPadding 意思是控件的绘制区域是否在padding里面.默认为true.如果你设置了此属性值为false,就能实现一个在布局上事半功陪的效果.先看一个效果图. 上图中的ListView顶部默认有一个间距,向上滑动后,间距消失,如下图所示. 如果使用margin或padding,都不能实现这个效果.加一个headerView又显得大材小用,而且过于麻烦.此处的clipToPadding配合paddingTop效果就刚刚好. 2.match_parent和wra

思科命令配置小技巧三:alias 命令

大家都用过手机上的快捷拨号设置 思科设备是否支持命令的快捷键定义呢 答案是肯定的 suzhouxiaoniu(config)#alias exec xx show ip inter bri  xx是自定义的快捷键名称,可以是数字 suzhouxiaoniu#xx 直接敲定义好的名称Interface                  IP-Address      OK? Method Status                ProtocolFastEthernet1/0          

在Axure中使用FontAwesome替换你的网站图标[axure小技巧]

你是不是还在为你的网站做一个很小的图标而忙碌着?你是不是还在为找一个图标导出百度或者谷歌?你有没有想过可以用字体来做一个图标代替普通的图片图标?这两天给公司做案例,由于自己又对设计不熟悉,寻找图标的苦差可不是很好做.同事分享了一个用字体代替图片做网站图标的资源,在此非常感谢!Font Awesome,原只为Bootstrap而设计的字体图标,不过,现在你可以单独用它来为你的网站工作.丢掉图片图标吧,跟我一起来用Font Awesome. 使用方法: 1. 下载 Font Awesome 官方网站

iOS 小技巧总结,绝对有你想要的

iOS 小技巧总结,绝对有你想要的 原文链接:http://www.jianshu.com/p/4523eafb4cd4 在这里总结一些 iOS 开发中的小技巧,能大大方便我们的开发,持续更新. —— 由 xcvxvxc分享 在这里总结一些iOS开发中的小技巧,能大大方便我们的开发,持续更新. UITableView的Group样式下顶部空白处理 在viewWillAppear里面添加如下代码: //分组列表头部空白处理 CGRect frame = myTableView.tableHeade

Nginx return 关键字配置小技巧

Nginx的return关键字属于HttpRewriteModule模块: 语法:return http状态码 默认值:无 上下文:server,location,if 该指令将结束执行直接返回http状态码到客户端. 支持的http状态码:200, 204, 400, 402-406, 408, 410, 411, 413, 416 , 500-504,还有非标准的444状态码. 使用方法: #不符合规则的返回403禁止访问 location /download/ {     rewrite