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

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

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

  1. Linux的95个小技巧

    Linux的95个小技巧 by WEB全栈工程师 on 2012 年 03 月 27 日 这里总结了Linux使用中的一些小技巧 1.实现RedHat非正常关机的自动磁盘修复 先登录到服务器,然后在/ ...

  2. Android开发的那些坑和小技巧

    1.android:clipToPadding 意思是控件的绘制区域是否在padding里面.默认为true.如果你设置了此属性值为false,就能实现一个在布局上事半功陪的效果.先看一个效果图. 上 ...

  3. 前端网络、JavaScript优化以及开发小技巧

    一.网络优化 YSlow有23条规则,中文可以参考这里.这几十条规则最主要是在做消除或减少不必要的网络延迟,将需要传输的数据压缩至最少. 1)合并压缩CSS.JavaScript.图片,静态资源CDN ...

  4. 最强 Android Studio 使用小技巧和快捷键

    写在前面 本文翻译自 Android Studio Tips by Philippe Breault,一共收集了62个 Android Studio 使用小技巧和快捷键. 根据这些小技巧的使用场景,本 ...

  5. ios开发中的小技巧

    在这里总结一些iOS开发中的小技巧,能大大方便我们的开发,持续更新. UITableView的Group样式下顶部空白处理 //分组列表头部空白处理 UIView *view = [[UIViewal ...

  6. Windows Azure一些小技巧集合

    我最近做了一个Windows Azure上面的项目,自己在做的过程中遇到了很多问题.有的是我自己摸索解决,有的是到网上寻找零碎的信息结合起来解决的.我感觉应当把某些解决方法集中一下,方便我以后查阅,也 ...

  7. FineUI小技巧(7)多表头表格导出

    前言 之前我们曾写过一篇文章 FineUI小技巧(3)表格导出与文件下载,对于在 FineUI 中导出表格数据进行了详细描述.今天我们要更进一步,介绍下如何导出多表头表格. 多表头表格的标签定义 在 ...

  8. FineUI小技巧(5)向子窗口传值,向父窗口传值

    前言 FineUI中经常会用到启用IFrame的Window控件,这样有助于从物理上进行代码解耦和.IFrame的引入就会涉及传值问题,如何在父窗口和子窗口之间相互传值呢? 向子窗口传值 向子窗口传值 ...

  9. YbSoftwareFactory 代码生成插件【二十一】:Web Api及MVC性能提升的几个小技巧

    最近在进行 YbSoftwareFactory 的流程功能升级,目前已经基本完成,现将用到的一些关于 Web Api 及 MVC 性能提升的一些小技巧进行了总结,这些技巧在使用.配置上也相当的简单,但 ...

随机推荐

  1. 编译安装PHP7并安装Redis扩展Swoole扩展

    编译安装PHP7并安装Redis扩展Swoole扩展 在编译php7的机器上已经有编译安装过php5.3以上的版本,从而依赖库都有了 本php7是编译成fpm-php 使用的, 如果是apache那么 ...

  2. acm数学(待续)

    意图写出http://www.cnblogs.com/kuangbin/archive/2012/08/28/2661066.html这个东西的完善版. 1.置换,置换的运算 poj 2369 Per ...

  3. win10无法使用内置管理员账户打开应用怎么办

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System \UIPI 右边有个默认的项.将它的值改成1

  4. PHP内核探索之变量(6)- 后续内核探索系列大纲备忘

    年前因为工作比较饱和,现在又忙着换工作的事情,基本停止了对博文的更新.后续的博文,还是慢慢补上吧. 为了不至于过于发散,先搞个未成形的大纲,如下: PHP内核探索之变量  不平凡的字符串 PHP内核探 ...

  5. java.outOfMemory

    http://www.kdgregory.com/index.php?page=java.outOfMemory Java Platform, Standard Edition HotSpot Vir ...

  6. js深拷贝和浅拷贝

    一.数组的深浅拷贝 在使用JavaScript对数组进行操作的时候,我们经常需要将数组进行备份,事实证明如果只是简单的将它赋予其他变量,那么我们只要更改其中的任何一个,然后其他的也会跟着改变,这就导致 ...

  7. Swift学习笔记--变量与常量

    1.Swift是一门强类型语言,不能为变量赋予其自身数据类型之外的值: 2.声明变量使用var关键字,声明常量使用let关键字: 3.声明变量或常量时没有对其指定类型且赋予了初值,则编译器会自动推断常 ...

  8. C语言位运算符及作用:与、或、异或、取反、左移和右移

    一.& 按位与 如果两个相应的二进制位都为1,则该位的结果值为1,否则为0应用:(1)清零 若想对一个存储单元清零,即使其全部二进制位为0,只要找一个二进制数,其中各个位符合一下条件:原来的数 ...

  9. BZOJ3503: [Cqoi2014]和谐矩阵

    题解: 如果第一行的数知道了,我们就可以推出其他行的数. 那么如何判断第一行的数的一种填法是否合法呢?很简单,我们递推出m+1行的数,当且仅当这一行都是0时满足题意. 那么,我们就有了一种想法. 直接 ...

  10. 重构16-Encapsulate Conditional(封装条件)

    当代码中充斥着若干条件判断时,代码的真正意图会迷失于这些条件判断之中.这时我喜欢将条件判断提取到一个易于读取的属性或方法(如果有参数)中.重构之前的代码如下: ) { return "doS ...