.NET数据访问集锦(二)编写自己的SqlHelper

  这里主要介绍一下使用DataReader读取数据,包括分页读取。DataReader只读向前,DataAdapter的Fill方法是一次性把查询到的所有数据取出来填充到DataTable或DataSet,下面的方法是使用DataReader只把当前页所需要的数据取出来添加到DataTable,效率要比使用DataAdapter的Fill方法高得多。

      一、创建一个类库项目,命名为DAO,并创建一个SqlHelper.cs类

using  System.Data;
using  System.Data.SqlClient;

namespace  DAO
{
    
public   class  SqlHelper
    {
        
// 数据库连接字符串,在实际应用中将其写在配置文件中,不要如此硬编码
         private   static   string  ConnString  =   " server=.;database=test;uid=sa;pwd=123456 " ;

        
public  SqlHelper()
        {
        }

        
public   static   void  FillDataTable( string  query, DataTable dt)
        {
            
using  (SqlConnection conn  =   new  SqlConnection(ConnString))
            {
                SqlCommand cmd 
=   new  SqlCommand(query, conn);
                conn.Open();
                SqlDataReader dr 
=  cmd.ExecuteReader();
                
int  cols  =  dr.VisibleFieldCount;
                
for  ( int  i  =   0 ; i  <  cols; i ++ )
                {
                    dt.Columns.Add(
new  DataColumn(dr.GetName(i), dr.GetFieldType(i)));
                }
                
while  (dr.Read())
                {
                    DataRow row 
=  dt.NewRow();
                    
for  ( int  i  =   0 ; i  <  cols; i ++ )
                    {
                        row[i] 
=  dr[i];
                    }
                    dt.Rows.Add(row);
                }
                dr.Close();
            }
        }
        
///   <summary>
        
///  分页读取数据
        
///   </summary>
        
///   <param name="query"> select查询语句 </param>
        
///   <param name="pageSize"> 每页显示数据数 </param>
        
///   <param name="currentPageIndex"> 当前页码 </param>
        
///   <param name="dt"> 存储数据的DataTable实例 </param>
         public   static   void  FillDataTable( string  query, int  pageSize, int  currentPageIndex, DataTable dt)
        {
            
// 读取数据的开始索引
             long  startIndex  =  (currentPageIndex  -   1 *  pageSize;
            
// 读取数据的结束索引
             long  endIndex  =  currentPageIndex  *  pageSize - 1 ;
            
// DataReader读取的当前数据行的索引
             long  readToIndex  =   - 1 ;

            
using  (SqlConnection conn  =   new  SqlConnection(ConnString))
            {
                SqlCommand cmd 
=   new  SqlCommand(query, conn);
                conn.Open();
                SqlDataReader dr 
=  cmd.ExecuteReader();
                
// 数据源中的列数
                 int  cols  =  dr.VisibleFieldCount;
                
// 构造DataTable结构
                 for  ( int  i  =   0 ; i  <  cols; i ++ )
                {
                    dt.Columns.Add(
new  DataColumn(dr.GetName(i), dr.GetFieldType(i)));
                }
                
// 读取数据,将数据一行一行添加到DataTable
                 while  (dr.Read())
                {
                    readToIndex
++ ;
                    
// 当DataReader指针在开始索引和结束索引闭区间时才读取数据构造DataRow
                    
// 并添加到DataTable
                     if  (readToIndex  >=  startIndex  &&  readToIndex  <=  endIndex)
                    {
                        DataRow row 
=  dt.NewRow();
                        
for  ( int  i  =   0 ; i  <  cols; i ++ )
                        {
                            row[i] 
=  dr[i];
                        }
                        dt.Rows.Add(row);
                    }
                }
                dr.Close();
            }

        }
    }
}

  二、测试,创建一个网站项目,添加对DAO项目的引用,设计如下界面

      .NET数据访问集锦(二)编写自己的SqlHelper

   GridView保持默认设置,不要设置自动分页,下面是5个Button和一个TextBox

  后台代码:   

using  System;
using  System.Web.UI.WebControls;
using  System.Data;
using  DAO;

public   partial   class  _Default : System.Web.UI.Page 
{
    DataTable dt 
=   new  DataTable();
    
protected   void  Page_Load( object  sender, EventArgs e)
    {
        
if  ( ! IsPostBack)
        {
            
if  (ViewState[ " CurrentPageIndex " ==   null )
            {
                ViewState[
" CurrentPageIndex " =   1 ;
            }
            BindData();
        }
    }
    
private   void  BindData()
    {
        
// SqlHelper.FillDataTableByDataAdapter("select * from BigData", dt);
        SqlHelper.FillDataTable( " select * from BigData " 10 int .Parse(ViewState[ " CurrentPageIndex " ].ToString()), dt);
        GridView1.DataSource 
=  dt;
        GridView1.DataBind();
    }
    
protected   void  GridView1_PageIndexChanging( object  sender, GridViewPageEventArgs e)
    {
        DateTime dt1 
=  DateTime.Now;
        GridView1.PageIndex 
=  e.NewPageIndex;
        BindData();
        DateTime dt2 
=  DateTime.Now;
        TimeSpan ts 
=  dt2  -  dt1;

        Response.Write(ts.Milliseconds.ToString());
    }
    
protected   void  btnFirst_Click( object  sender, EventArgs e)
    {
        ViewState[
" CurrentPageIndex " =   1 ;
        BindData();
    }
    
protected   void  btnPrev_Click( object  sender, EventArgs e)
    {
        ViewState[
" CurrentPageIndex " =   int .Parse(ViewState[ " CurrentPageIndex " ].ToString())  -   1 ;
        BindData();
    }
    
protected   void  btnNext_Click( object  sender, EventArgs e)
    {
        ViewState[
" CurrentPageIndex " =   int .Parse(ViewState[ " CurrentPageIndex " ].ToString())  +   1 ;
        BindData();
    }
    
protected   void  btnGo_Click( object  sender, EventArgs e)
    {
        ViewState[
" CurrentPageIndex " =  txtPage.Text.Trim();
        BindData();
    }
}

  创建一个两列的表,插入一百万条数据测试

declare   @num   int
set   @num = 1
while ( @num < 1000001 )
 
begin
    
insert  BigData  values ( @num )
    
set   @num   =   @num + 1
 
end

  运行后界面:

  .NET数据访问集锦(二)编写自己的SqlHelper

   翻页响应很快,比直接使用DataAdapter的Fill方法填充DataTable,然后使用GridView自动翻页效率高的多。

        数据翻页功能的实现还有其它一些方法,比如TOP、row_number()over(SQL Server 2005/2008)、存储过程等,有兴趣可以测试一下。

        本例提供的方法仅供参考。

你可能感兴趣的:(.net)