GridView&ObjectDataSource新特性小記 懶人篇(一) 分頁上路

Posted on 2006-04-13 19:34 笑看千秋_R

懶"歸正傳:
         最近開場廢話是多了點(可能是參加會議太多鬧的.. ^_^!!).馬上請出GridView & ObjectDataSource.
下面我將逐步展現一個分頁的案例.

案例環境: WindowsXP SP2, VS2005 Team Suite,SqlServer2005(沒有比這更糟的了....)
要求:         瞭解數據綁定控件的結構,數據源的運行機制,以及簡單的綁定控件設計實現(那些內容足夠再寫一篇教程了,這裏不再多敘.)
參 考:         MSDN中提到,ObjectDataSource是唯一支持界面分頁的數據源(除非自己來繼承造一個,汗!),但示例仍    然是用SqlDataSource做數據源介紹的GirdView綁定.難道MS這麼小氣???(ps:打死俺也不說).

那好,就從那句介紹開始,咱們自己動手整出一個來.
按照常規,先準備一張表和一些存儲過程,如下:

 

Table:MyUsers 
     UserID (
int,primary key,identity)  --自動增加字段,用戶ID標識列
     UserName (nvarchar(50),not null)   --用戶名
     Description (nvarchar(50),not null)--備註

Procedure:

CREATE PROCEDURE [dbo].[AddUser] --增加一個用戶
    @UserName nvarchar(50),
    
@Description nvarchar(50)
AS
BEGIN
    
SET NOCOUNT ON;

    
begin transaction t
    
    
insert into MyUsers(UserName,Description) 
    
values(@UserName,@Description)
    
    
if @@error <> 0
    
begin 
        
rollback transaction t
    
end
    
else
    
begin 
        
commit transaction
    
end
END

CREATE PROCEDURE [dbo].[DeleteUserByUserID]  --刪除一個用戶
    @UserID int
AS
BEGIN
    
SET NOCOUNT ON;

    
Begin Transaction t

    
delete from MyUsers where UserID =@UserID

    
if @@error <> 0
        
begin 
            
rollback transaction t
        
end 
    
else
        
begin
            
commit transaction
        
end    
END

CREATE PROCEDURE [dbo].[UpdateUser] --修改用戶姓名或備註
    @UserID int,
    
@UserName nvarchar(50),
    
@Description nvarchar(50)
AS
BEGIN
    
SET NOCOUNT ON;

    
begin transaction t
    
    
update MyUsers 
    
set UserName = @UserName,
        Description 
= @Description 
    
where UserID = @UserID

    
if @@error <> 0 
        
begin
            
rollback transaction t
        
end
    
else
        
begin
            
commit transaction  t
        
end
END

CREATE PROCEDURE [dbo].[GetUsers] --得到用戶列表,注意這裏的參數
    @RowIndex int,
    
@RecordCount int
AS
BEGIN
    
SET NOCOUNT ON;

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

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

CREATE PROCEDURE [dbo].[GetUsersCount]    
AS
BEGIN
    
SET NOCOUNT ON;
    
select count(UserID) from MyUsers
END


這裏詳細說明一下倒數兩個存儲過程,GetUsers的參數RowIndex,不是頁碼(傳說中的PageIndex),而是行索引,且從 0開始.這點特別要注意,因爲要讓ObjectDataSource自動取得當前需要的數據(界面級分頁意味着當前需要顯示多少數據只向數據庫取多少,並 不會像其他數據源全總取出消耗性能.),依據也就是行索引和增量.GetUsersCount這個存儲過程是爲ObjectDataSource分頁提供 總數的,它與分頁的存儲過程要保持一致.特別指的是有分頁條件的情況,本人經常忘記(^_^||).否則GridView顯示會不正常.

在WebSite新建一個DAL,假定類名爲DataManager,給出代碼片段如下:

 

using System;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections;
using System.Collections.Generic;

/// <summary>
/// DataAccessLayer
/// </summary>

public class DataManager
{
    
private SqlConnection con = null//連接對象
    private SqlCommand cmd = null;  //command執行對象
    private SqlDataAdapter da = null//適配器對象

    
/// <summary>
    
/// DAL對象構造
    
/// </summary>

    public DataManager()
    
{
        
//
        
// TODO: Add constructor logic here
        
//
    }


    
/// <summary>
    
/// 打開數據庫連接
    
/// </summary>

    private void OpenConnection()
    
{
        
try
        
{
            
string conString = ConfigurationManager.ConnectionStrings["localDB"].ConnectionString;
            con 
= new SqlConnection(conString);
            
if (ConnectionState.Closed == con.State)
            
{
                con.Open();                    
            }

        }

        
catch (SqlException ex)
        
{
            
throw new Exception("數據庫無法訪問", ex);
        }

    }


    
/// <summary>
    
/// 關閉數據庫連接
    
/// </summary>

    private void CloseConnection()
    
{
        
if (ConnectionState.Open == con.State)
        
{
            
try
            
{
                con.Close();
            }

            
catch (SqlException ex)
            
{
                
throw new Exception("數據庫無法關閉", ex);
            }

        }

    }


    
/// <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 
= "GetUsers";
            
            SqlParameter spRowIndex 
= new SqlParameter("@RowIndex",SqlDbType.Int,4);
            spRowIndex.Direction 
= ParameterDirection.Input;        
            SqlParameter spRecordCount 
= new SqlParameter("@RecordCount",SqlDbType.Int,4);
            spRecordCount.Direction 
= ParameterDirection.Input;

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

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

            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 
= "GetUsersCount";
            
int count = Convert.ToInt32(cmd.ExecuteScalar().ToString());
            
return count;
        }

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

        
finally
        
{
            CloseConnection();
        }

    }

 

對DAL也有幾項說明,DataManager.GetUsers(int rowIndex, int recordCount)方法的參數只能有兩個,
參數名可以隨意,但意義卻要與調用的存儲過程GetUsers要一致,rowIndex必須是行索引,recordCount必須是頁顯示量.
OK!接下來在頁面上放上一個GridView和一個ObjectDataSource,設置代碼片段如下:


<asp:GridView ID="gvMyUsers" runat="server" AllowPaging="True" CellPadding="4" DataSourceID="objMyUsers" ForeColor="#333333" GridLines="None" AutoGenerateDeleteButton="True" AutoGenerateEditButton="True" AutoGenerateColumns="False" DataKeyNames="UserID" PageSize="10">
<FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
<RowStyle BackColor="#EFF3FB" />
<EditRowStyle BackColor="#2461BF" />
<SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" />
<PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" />
<HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
<AlternatingRowStyle BackColor="White" />
</asp:GridView>    
<asp:ObjectDataSource ID="objMyUsers" runat="server" EnablePaging="True" MaximumRowsParameterName="recordCount" 
SelectCountMethod
="GetUsersCount" SelectMethod="GetUsers" StartRowIndexParameterName="rowIndex" TypeName="DataManager">
</asp:ObjectDataSource>

指定每頁顯示最大數據量(頁顯示量)的參數:
MaximumRowsParameterName="recordCount"
指定取得數據總數方法:
SelectCountMethod="GetUsersCount"
指定分頁方法:
SelectMethod="GetUsers"
指定起始行參數:
StartRowIndexParameterName="rowIndex"
指定前面方法所屬類名(全限定名):
TypeName="DataManager
這幾個設置是必須的,一定要對應.

現在輕輕的點擊一下運行吧(什麼什麼?還沒寫事件?...我說老鐵,都啥年月了,懶人還有用那玩兒嗎?).到這裏,一個最快速的分頁其實已經做完了.

前面的步驟都是必須的,但仍然可以有一些變化.比如,若你已經按以往的辦法寫好了一個類似於

Create Procedure GetUsers
    
@PageIndex int,
    
@PageSize int
as
begin
    
end
        這樣的存儲過程了,沒關係,你在DAL的DataManager.GetUsers(int rowIndex, int recordCount)這裏,
把rowIndex,recordCount在調用存儲過程前轉換成PageIndex,PageSize就好了,也不過是
PageIndex = rowIndex/recordCount +1; PageSize =recordCount;這樣的語句就能搞定啦.再或者改存儲過程裏面也行(雖然有點不值得),不多說了.自己耍一把就知道了.
        你一定心裏還有疑問,沒錯,DataManager.GetUsers(int rowIndex, int recordCount)這個方法,更多時候需要多一些參數,也就是說,我們分頁取數據的過程,還需要一些篩選條件,但這個方法是要給 ObjectDataSource的selectMethod方法,不能增加別的參數,形成矛盾怎麼辦??欲知解決之道,且等下回分解.....(快跑 啊.....雞蛋來啦!!)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章