懶"歸正傳:
最近開場廢話是多了點(可能是參加會議太多鬧的.. ^_^!!).馬上請出GridView & ObjectDataSource.
下面我將逐步展現一個分頁的案例.
案例環境: WindowsXP SP2, VS2005 Team Suite,SqlServer2005(沒有比這更糟的了....)
要求: 瞭解數據綁定控件的結構,數據源的運行機制,以及簡單的綁定控件設計實現(那些內容足夠再寫一篇教程了,這裏不再多敘.)
參 考: MSDN中提到,ObjectDataSource是唯一支持界面分頁的數據源(除非自己來繼承造一個,汗!),但示例仍 然是用SqlDataSource做數據源介紹的GirdView綁定.難道MS這麼小氣???(ps:打死俺也不說).
那好,就從那句介紹開始,咱們自己動手整出一個來.
按照常規,先準備一張表和一些存儲過程,如下:
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 desc) as 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.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
這幾個設置是必須的,一定要對應.
現在輕輕的點擊一下運行吧(什麼什麼?還沒寫事件?...我說老鐵,都啥年月了,懶人還有用那玩兒嗎?).到這裏,一個最快速的分頁其實已經做完了.
前面的步驟都是必須的,但仍然可以有一些變化.比如,若你已經按以往的辦法寫好了一個類似於
@PageIndex int,
@PageSize int
as
begin
end
把rowIndex,recordCount在調用存儲過程前轉換成PageIndex,PageSize就好了,也不過是
PageIndex = rowIndex/recordCount +1; PageSize =recordCount;這樣的語句就能搞定啦.再或者改存儲過程裏面也行(雖然有點不值得),不多說了.自己耍一把就知道了.
你一定心裏還有疑問,沒錯,DataManager.GetUsers(int rowIndex, int recordCount)這個方法,更多時候需要多一些參數,也就是說,我們分頁取數據的過程,還需要一些篩選條件,但這個方法是要給 ObjectDataSource的selectMethod方法,不能增加別的參數,形成矛盾怎麼辦??欲知解決之道,且等下回分解.....(快跑 啊.....雞蛋來啦!!)