zoukankan      html  css  js  c++  java
  • [小技巧]让你的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 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();
    

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

  • 相关阅读:
    Java 中 Comparable 和 Comparator 接口及其简单应用(一)
    MD5加密算法失效及解决方法
    mybatis bug (二):Error updating database. Cause: java.sql.SQLIntegrityConstraintViolationException: Column 'third_party_id' cannot be null
    IDEA 显示波浪形警告信息,但是程序没有报错
    为用户注册界面添加修改密码选项
    Java 程序读取Mysql数据库时间信息,与真实时间相差 13 小时
    Http 错误:"status":404,"error":"Not Found","message":"No message available”,”path":""
    mybatis bug (一):Failed to execute goal org.mybatis.generator:mybatis-generator-maven-plugin
    归并排序及数组中逆序对的数量
    ITUNES更改备份保存路径
  • 原文地址:https://www.cnblogs.com/caption/p/3966523.html
Copyright © 2011-2022 走看看