2.1 使用DataSet構建3層結構
開發3層結構利用系統時,在表示層、業務邏輯層、數據訪問層各層中如何使用DataSet呢?DataSet在3層結構中的層次以下圖所示:
從圖中可以看出,在3層結構中,DataSet的構建和解析工作主要在表示層、數據訪問層完成,業務邏輯層主要對DataSet中的數據進行加工、處理和傳遞。簡單地說,DataSet是全部3層結構中數據傳遞的介質。
2.2 3層結構中DataSet的使用
2.2.1 在表示層中使用DataSet
在表示層中使用DataSet需要做兩件事。
(1)將DataSet中的數據展現給用戶。
在Winform窗體控件中,DataGridView(數據表格)控件、ComboBox(下拉列表)控件等,他們都有1個數據源屬性(DataSource),1般我們可以將Dataset或DataTable綁定到DataSource屬性上便可實現數據展現。
(2)將用戶的要求數據填充到DataSet中。
要將用戶的要求數據填充到DataSet中,我們首先需要構建1個結構與用戶要求數據結構相同的DataTable,然后將用戶的要求數據填充到構建好的DataTable中,最后將DataTable添加到DataSet中。
表示層的DataSet如圖2.3所示。
完成將DataSet中的數據展現給用戶和將用戶的要求數據填充到DataSet中的具體實現進程將在下面的綜合示例中具體演示。
2.2.2 在業務邏輯中使用DataSet
在業務邏輯層使用DataSet需要做下面幾件事:
(1)將接收的DataSet傳遞到下1層。
當業務邏輯層收到數據訪問層返回的DataSet后接著將DataSet傳遞給表示層,或是將表示層要求的DataSet傳遞給數據訪問層。
(2)根據用戶要求對DataSet中的數據進行處理。
當業務邏輯層收到要求或響應的DataSet后,根據用戶的要求(例如:條件挑選數據)或業務規則會對DataSet中的數據進行處理。
業務邏輯層的DataSet以下圖所示:
2.2.3 在數據訪問層中使用DataSet
在數據訪問層中使用DataSet
在數據訪問層中使用DataSet需要做以下事情:
(1)將數據庫中的數據填充到DataSet中。
當用戶的要求時查詢要求時,數據訪問層需要實現對數據庫的查詢訪問,并將響應結果填充到DataSet中。
(2)將DataSet中的數據保存到數據庫中。
當用戶的要求時數據保存要求時,數據訪問層首先對收到的DataSet進行解析,然后將解析出的數據保存到數據庫中。
數據訪問層的DataSet以下圖所示:
從上面的討論中,我們發現DataSet在3層結構的每層中都扮演側重要的數據載體角色,而每層中基本上都包括了創建DataSet、填充數據、傳遞DataSet,從DataSet中提取數據等幾個步驟。
2.3 如何創建DataSet
DataSet的構建有兩種方法。
(1)通過DataAdapter(數據適配器)的Fill方法將數據直接填充到DataSet中。
(2)通過手動編碼自定義DataTable(數據表)、DataColumn(數據列)、DataRow(數據行),然后將數據表添加到DataSet中。
首先,我們對DataSet做1個回顧,1個DataSet是由多個DataTable組成,而1個DataTable又是由多個DataColumn和多個DataRow組成。
接下來,我們來分別對DataTable、DataColumn、DataRow進行深入討論。
1. DataTable
DataTable是內存中的1個關系數據表,可以獨立創建使用,也能夠作為DataSet的1個成員使用。如何將DataTable作為DataSet的1個成員使用呢?首先,我們需要創建1個DataTable對象,其次通過使用Add方法將其添加到DataSet對象的Tables集合中,以下所示:
DataSet dsClass=newDataSet();
DataTable dtClass=newDataTable("Class");
dsClass.Tables.Add(dtClass);
如果我們沒有指定DataTable名稱時把DataTable添加到DataSet中,該表會得到1個從“0”開始遞增的默許表名(例:Table0、Table1、Table2).
2. DataColumn
DataColumn是創建DataTable的基礎,我們通過向DataTable中添加1個或多個DataColumn對象來定義DataTable的結構。DataColumn有1些經常使用屬性用于對輸入數據的限制,例如:數據類型、數據長度、默許值等,見下表:
屬 性 |
說 明 |
AllowDBNull |
是不是允許空值 |
ColumnName |
DataColumn的名稱 |
DataType |
存儲的數據類型 |
MaxLength |
獲得或設置文本列的最大長度 |
DefaultValue |
默許值 |
Table |
所屬的DataTable的名稱 |
Unique |
DataColumn的值是不是唯1 |
定義DataColumn有兩種方法,分別為示例1、示例2:
示例1:
DataColumnclassName=new DataColumn();
className.ColumnName= "ClassName";
className.DataType=System.Type.GetType("System.String");
className.MaxLength=50;
示例2:
DataColumn className=newDataColumn("ClassName",typeof(string));
className.MaxLength=50;
3. DataRow
DataRow表示DataTable中包括的實際數據,我們可以通過DataRow將數據添加到用DataColumn定義好的DataTable中,如示例3所示:
DataColumn className=newDataColumn("ClassName",typeof(string));
className.MaxLength=50;
//創建1個新的數據行
DataRowdrClass=dtClass.NewRow();
drClass["className"]=this.txtClassName.Text.Trim();
2.4 如何自定義DataSet
自定義DataSet主要步驟以下:
①、 創建DataSet對象。
②、 創建DataTable對象。
③、 創建DataColumn對象構建表結構。
④、 將創建好的表結構添加到表中。
⑤、 創建DataRow對象新增數據。
⑥、 將數據插入到表中。
⑦、 將表添加到DataSet中。
示例以下:
DataSet dsClass=newDataSet();
//創建班級表
DataTable dtClass=newDataTable("Class");
//創建年級ID列
DataColumndcClassName=new DataColumn("ClassName",typeof(string));
className.MaxLength=50;
//創建年級ID列
DataColumndcGradeId=new DataColumn("GradeId",typeof(int));
//將定義好列添加到班級表中
dtClass.Columns.Add(dcClassName);
dtClass.Columns.Add(dcGradeID);
//創建1個新的數據行
DataRowdrClass=dtClass.NewRow();
drClass["className"]=this.txtClassName.Text.Trim();
drClass["gradeID"]=objGrade.GetGradeIDByGradeName(this.cboGrade.Text.Trim());
//將新的數據行插入到班級表中
dtClass.Rows.Add(drClass);
//將班級表添加到DataSet中
dsClass.Tables.Add(dtClass);
如上所述,我們學習了如何構建DataSet和如何將數據填充到DataSet中。
2.5 如何獲得DataSet中的數據
從DataSet中獲得數據有兩種方式:
(1)通過指定DataSet中的具體DataTable的某行某列來獲得數據。
步驟以下:
①、 通過表名,從DataSet中獲得指定的DataTable。
②、 通過索引,從DataTable中獲得指定的DataRow。
③、 通過列名,從DataRow中獲得指定列的數據。
以獲得班級信息為例:
示例以下:
//得到班級名稱
dsClass.Tables["Class"].Rows[0][ "ClassName"];
//得到年級ID
dsClass.Tables["Class"].Rows[0][ "GradeID"];
(2)將DataSet的數據直接綁定到數據控件上。
2.6 實現數據訪問層
在第1章的項目基礎上,實現對業務邏輯層的完善與修改。
#region Public Methods
///<summary>
///獲得所有學員信息
///</summary>
///<returns>所有學員信息數據集</returns>
public DataSet GetAllStudents()
{
DataSet ds=new DataSet();
SqlConnection conn=new SqlConnection(connstring);
SqlDataAdapter objAdapter=new SqlDataAdapter("usp_SelStudentInfo",conn);
//usp_SelStudentInfo 為查找學生存儲進程信息
objAdapter.SelectCommand.CommandType=CommandType.StoredProcedure;
objAdapter.Fill(ds,"stuTable");
conn.Close();
conn.Dispose();
return ds;
}
#endregion
//根據年級編號取得班級信息,參考代碼以下:
public DataSetGetClassByGradeID(int gradeID)
{
DataSet ds = new DataSet();
SqlConnection conn = new SqlConnection(connString);
SqlDataAdapter objAdapter = newSqlDataAdapter( "usp_SelectClassesByGradeID",conn);
objAdapter.SelectCommand.CommandType = CommandType.StoredProcedure;
objAdapter.SelectCommand.Parameters.Add("@GradeID", SqlDbType.Int).Value = gradeID;
objAdapter.Fill(ds, "classTable");
conn.Close();
conn.Dispose();
return ds;
}
/// 根據性別挑選學員信息,并按姓名排序
public DataViewGetStudentBySex(string sex)
{ //實例化DataView對象
DataView dvStudent = new DataView();
//獲得從數據層返回的學生信息表
dvStudent.Table = studentController.SelectAllStudent().Tables["studentTable"];
//根據條件過濾信息
if (sex.Trim() == "男")
dvStudent.RowFilter ="Sex='男'";
if (sex.Trim() == "女")
dvStudent.RowFilter ="Sex='女'";
//按學生姓名降序排序
dvStudent.Sort = “StudentName DESC”;
//返回過濾后的數據視圖
return dvStudent;
}
//其他代碼見上課案例.
【
在用3層架構開發利用程序時,首先根據需求編輯界面數據展現方式,然后按底層到頂層的順序實現數據訪問層、業務邏輯層、表示層。
在實現數據訪問層時,為了使我們開發的利用程序易于保護,我們常把不同表的數據訪問代碼封裝在不同的類里,1般情況下1個類對應1張表。
】
小結
n 用Ado.Net實現3層結構利用程序時,DataSet的主要作用是3層之間數據傳遞的載體。
n 用Ado.Net實現3層結構利用系統時,數據訪問層主要使用的類有:
ü SqlConnection類,實現數據庫連接。
ü SqlCommand類,履行Sql命令。
ü SqlDataReader類,讀取數據。
ü SqlDataAdapter類,履行Sql命令,返回DataSet。
ü DataSet類,封裝用戶要求數據。
n 用Ado.Net履行帶參數的Sql命令時,需要使用參數化類Parameters的Add方法為Sql命令添加參數,包括參數名稱、參數類型。結合Ado.Net章節來重新使用參數化對象對數據訪問層、業務邏輯層進行重新代碼架構。
n 業務邏輯層實現數據傳遞、處理時,首先援用數據訪問層,其次實例化數據訪問對象,最后調用數據訪問層功能,并實現數據處理。
作業:
完善第1章自己已架構好的MIS系統,豐富完善數據訪問層、業務邏輯層和表示層,要求:
1. 利用本章講授的DataSet進行數據傳遞;
使用存儲進程來操作數據。