GridView&ObjectDataSource 新特性小記 懶人篇(二) 分頁加速

Posted on 2006-04-17 18:43 笑看千秋_R
Table: MyUsers
  
@UserID (int,primary key,identity),
  
@UserName (nvarchar(50),not null),
  
@Description (nvarchar(50),not null),
  
@Status (bit,not null)

Procedure:
  
create procedure [dbo].[GetUsersByStatus]  --通過狀態得到用戶列表
    @RowIndex int,
    
@RecordCount int,
    
@Status bit
AS
BEGIN
    
SET NOCOUNT ON;

    
With VUsers as (
        
select *,row_number() over (order by UserID descas RowNum
        
from MyUsers where Status = @Status
)

    
select * from VUsers 
    
where RowNum > @RowIndex and RowNum <= (@RowIndex+@RecordCount)    
END

CREATE PROCEDURE [dbo].[GetUsersCountByStatus]  --取得通過狀態得到用戶列表的總數
    @Status bit
AS
BEGIN
    
SET NOCOUNT ON;
    
select count(UserID) from MyUsers where Status = @Status
END

        在WebSite的DataManager中,再增加兩個帶參數的分頁查詢的方法.下面介紹兩種帶參的分頁查詢方法的寫法(原因是和ObjectDataSource的運行機制有關):
(1)
MSDN中提到,ObjectDataSource有這樣一個事件:ObjectDataSources_Created,它將在每次ObjectDataSource
初始化TypeName指定的類時觸發.也就是說,如果分頁的方法需要除RowIndex,RecordCount外的其他參數的話可以
藉助此事件來增加參數.由此,可以按下面方式增加分頁方法:

1.在DataManager類中,增加一個屬性
 
private bool _Status;
 
public bool Status
 
{
     
get{return  _Status;}
     
set{_Status = values;}
 }


2.增加一個方法

public DataSet GetUsers(int rowIndex,int recordCount)
{
    
/// <summary>
    
/// 取得用戶列表
    
/// </summary>
    
/// <param name="rowIndex">行索引</param>
    
/// <param name="recordCount">頁顯示量(增量)</param>
    
/// <returns>用戶列表數據集</returns>

    public DataSet GetUsers(int rowIndex, int recordCount)
    
{
        OpenConnection();
        
try
        
{
            cmd 
= new SqlCommand();
            cmd.Connection 
= con;
            cmd.CommandType 
= CommandType.StoredProcedure;
            cmd.CommandText 
= "GetUsersByStatus";
            
            SqlParameter spRowIndex 
= new SqlParameter("@RowIndex",SqlDbType.Int,4);
            spRowIndex.Direction 
= ParameterDirection.Input;        
            SqlParameter spRecordCount 
= new SqlParameter("@RecordCount",SqlDbType.Int,4);
            spRecordCount.Direction 
= ParameterDirection.Input;
        SqlParameter spStatus 
= new SqlParameter("@Status", SqlDbType.Bit, 1);
            spStatus.Direction 
= ParameterDirection.Input;

            cmd.Parameters.Add(spRowIndex);
            cmd.Parameters.Add(spRecordCount);
        cmd.Parameters.Add(spStatus); 
//在這裏將增加的參數值隱式加入到查詢

            spRowIndex.Value 
= rowIndex;
            spRecordCount.Value 
= recordCount;
        spStatus.Value 
= _Status;
        
            da 
= new SqlDataAdapter(cmd);
            DataSet ds 
= new DataSet();
        
            da.Fill(ds, 
"MyUsers");

            
return ds;
    }

        
catch (SqlException ex)
        
{
            
throw new Exception("無法取得有效數據", ex);
        }

        
finally
        
{
            CloseConnection();
        }

    }


    
/// <summary>
    
/// 根據用戶狀態取得用戶總數
    
/// </summary>
    
/// <returns>用戶總數</returns>

    public int GetUsersCount()
    
{
        OpenConnection();
        
try
        
{
            cmd 
= new SqlCommand();
            cmd.Connection 
= con;
            cmd.CommandType 
= CommandType.StoredProcedure;
            cmd.CommandText 
= "GetUsersCountByStatus";

            SqlParameter spStatus 
= new SqlParameter("@Status", SqlDbType.Bit, 1);
            spStatus.Direction 
= ParameterDirection.Input;

            cmd.Parameters.Add(spStatus);

            spStatus.Value 
= _Status;

            
int count = Convert.ToInt32(cmd.ExecuteScalar().ToString());
            
return count;
        }

        
catch (SqlException ex)
        
{
            
throw new Exception("無法取得有效數據", ex);
        }

        
finally
        
{
            CloseConnection();
        }

    }

}


3.在頁面增加一個DropDownList,設置如下
<asp:DropDownList ID="ddShowUsersByStaus" runat="server" AutoPostBack="True">               
    
<asp:ListItem Selected="True" Value="all">全部</asp:ListItem>
                
<asp:ListItem Value="false">禁用</asp:ListItem>
                
<asp:ListItem Value="true">激活</asp:ListItem>
</asp:DropDownList></div>

4.在WebSite增加一個事件
 
protected ObjectDataSource_Created(object sender, ObjectDataSourceEventArgs e)
 
{
     
if(!ddShowUsersByStaus.SelectedValue.Equals("all"))
     
{
         DataManager  dm  
= (DataManager)e.GetInstance();
         dm.Status 
= ddShowUsersByStaus.SelectedValue;
     }

 }
        這樣,在選擇了用戶狀態之後,ObjectDataSource會首先將選擇的值賦給Status屬性,然後纔會去調用GetUsers()方法取得用戶列表 至此,我們可以在不必改變原有方法接口的前提下,解決增加了參數的問題.
 然而,這樣似乎還是很麻煩,無謂在DataManager類中增加屬性,使得Web和DataManager成爲緊耦合應用,同時也非"懶人"所爲.再介紹 一種更爲靈活的方式供大家參考


(2)
ObjectDataSource類的SelectParameters是可以動態改變的,據此,我們按下面的順序來更改應用.

1.Datamanager中重載GetUsers()和GetUsersCount()兩個方法.代碼如下

public DataSet GetUsers(int rowIndex, int recordCount,bool status)
    
{
        OpenConnection();
        
try
        
{
            cmd 
= new SqlCommand();
            cmd.Connection 
= con;
            cmd.CommandType 
= CommandType.StoredProcedure;
            cmd.CommandText 
= "GetUsersByStatus";

            SqlParameter spRowIndex 
= new SqlParameter("@RowIndex", SqlDbType.Int, 4);
            spRowIndex.Direction 
= ParameterDirection.Input;
            SqlParameter spRecordCount 
= new SqlParameter("@RecordCount", SqlDbType.Int, 4);
            spRecordCount.Direction 
= ParameterDirection.Input;
            SqlParameter spStatus 
= new SqlParameter("@Status", SqlDbType.Bit, 1);
            spStatus.Direction 
= ParameterDirection.Input;

            cmd.Parameters.Add(spRowIndex);
            cmd.Parameters.Add(spRecordCount);
            cmd.Parameters.Add(spStatus);

            spRowIndex.Value 
= rowIndex;
            spRecordCount.Value 
= recordCount;
            spStatus.Value 
= status;            

            da 
= new SqlDataAdapter(cmd);
            DataSet ds 
= new DataSet();

            da.Fill(ds, 
"MyUsers");

            
return ds;            
        }

        
catch (SqlException ex)
        
{
            
throw new Exception("無法取得有效數據", ex);
        }

        
finally
        
{
            CloseConnection();
        }

    }


    
public int GetUsersCount(bool status)
    
{
        OpenConnection();
        
try
        
{
            cmd 
= new SqlCommand();
            cmd.Connection 
= con;
            cmd.CommandType 
= CommandType.StoredProcedure;
            cmd.CommandText 
= "GetUsersCountByStatus";

            SqlParameter spStatus 
= new SqlParameter("@Status", SqlDbType.Bit, 1);
            spStatus.Direction 
= ParameterDirection.Input;

            cmd.Parameters.Add(spStatus);

            spStatus.Value 
= status;

            
int count = Convert.ToInt32(cmd.ExecuteScalar().ToString());
            
return count;
        }

        
catch (SqlException ex)
        
{
            
throw new Exception("無法取得有效數據", ex);
        }

        
finally
        
{
            CloseConnection();
        }

    }


2.在頁面增加DropDownList設置如下:
<asp:DropDownList ID="ddShowUsersByStaus" runat="server" AutoPostBack="True" 
OnSelectedIndexChanged
="ddShowUsersByStaus_SelectedIndexChanged">
    
<asp:ListItem Selected="True" Value="all">全部</asp:ListItem>
    
<asp:ListItem Value="false">禁用</asp:ListItem>
    
<asp:ListItem Value="true">激活</asp:ListItem>
</asp:DropDownList>

3.在DropDownList的SelectedIndexChanged事件增加代碼:

protected void ddShowUsersByStaus_SelectedIndexChanged(object sender, EventArgs e)
{
    objMyUsers.SelectParameters.Clear();
    gvMyUsers.PageIndex 
= 0;
    
if ("all".Equals(ddShowUsersByStaus.SelectedValue))
    
{

    }


    
else
    
{
        Parameter pStatus 
= new Parameter("status", TypeCode.Boolean);
        
        objMyUsers.SelectParameters.Add(pStatus);
        pStatus.DefaultValue 
= ddShowUsersByStaus.SelectedValue;
    }
       
}

        如何?這樣看上去只是給ObjectDataSource的參數集合動態增加了一個參數,它自己就會去調用重載後的分頁方法,省得我們在專門指定 SelectMethod.編碼簡潔多了,維護起來也更容易,增加分頁的條件無非是增加重載的方法和變更動態增加參數的代碼,無意間發現這就是"開-閉" 原則的小應用.(估計沒人在乎這個吧...)

        採用GridView作爲數據綁定控件,好處在於ObjectDataSource會根據GridView的變化自動向數據庫取出當前需要的數據,而不用 我們爲它擔憂一絲一毫.至少不用爲取得空數據和頁碼不正確睡不着覺了.數據操作應該是完整的增刪查改.我們把查詢做得很徹底了,後面將介紹增加,刪除,修 改記錄的操作,我想,GridView&ObjectDataSource
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章