強類型數據集
強類型數據集實現為一系列的類,這些類派生自組成數據集的那些基類。派生於DataSet的強類型數據集,派生於DataTable的強類型數據表,派生於DataRow的強類型數據行。這些派生類都定義了多個附加的屬性和方法,為基礎類數據提供了類型安全的訪問。
TypedDataSet.TypedDataTable[n]. TypedProperty
1) TypedDataSet:強類型數據集,返回強類型的數據集。
2) TypedDataSet.TypedDataTable:強類型數據表,返回強類型的數據表
3) TypedDataTable[n]:強類型索引,返回強類型數據行
4) TypedProperty:強類型列屬性。列的強類型訪問,返回列類型的實例。
DataSet. Tables[n]. Rows[m][ DataColumn| int |string columnName]
1) DataSet:DataSet返回。
2) Tables[n]:返回DataTable。
3) Rows[m]:返回DataRow。
4) Rows[m][ DataColumn| int |string columnName]:返回Object類型的引用。
強類型類使用了Partial類特性,Partial類允許一個類定義存在於一個項目的多個檔案中。使用類允許在項目中的某個單獨的檔案中為強類型數據集補充代碼去實現驗證邏輯或商業邏輯。如果重新生成強類型數據集,這個單獨檔案的代碼不會受到影響。
1) 強類型數據表屬性
提供了對強類型數據集中強類型數據表實例的類型安全的訪問。提供了類型安全,並且可以提高設計效率和運行效率(主要相對於字元串而言)。
(1) DataSet中,Tables索引器(通過集合訪問)
public DataTable this [string name| int index] { get; }
DataTable employees = dataset.Tables[“Employees”|0];
(2) 強類型數據集中,強類型數據表屬性(通過私有數據成員tableEmployees來訪問表對象)
public EmployeesDataTable Employees
{
get {return this.tableEmployees;}
}
EmployeesDataTable employees = dataset. Employees;
1) DataColumn的命名屬性
對於數據表中的每個列,都有一個對應類型為DataColumn的命名屬性,這些屬性可以通過名稱來獲得這些數據列的類型信息訪問。可以提高設計效率和運行效率(主要相對於字元串而言)。
(1) DataTable中, Columns索引器(通過集合訪問)
public DataColumn this [string name| int index] { get; }
DataColumn employeeIDColumn = dataset.Tables[“EmployeeID”|0];
(2) 強類型數據表中,DataColumn的命名屬性(通過私有數據成員訪問)
public global::System.Data.DataColumn EmployeeIDColumn
{
get { return this.columnEmployeeID; }
}
DataColumn employeeIDColumn = dataset. EmployeeIDColumn;
2) 疊代訪問及強類型索引器(均訪問數據行集合)
強類型數據表提供了一個強類型數據行索引器,通過它可以用類型安全的強類型數據表類的實例訪問表中的所有強類型數據行。提供了類型安全。
實現了疊代接口IEnumerable,可以疊代訪問表中的所有強類型數據行。
(1) DataTable中, 未實現疊代接口IEnumerable,無DataRow索引器和Count屬性,不能直接疊代訪問表中的數據行,只能通過數據行集合疊代訪問表中的數據行。
public DataRow this [int index { get; }
public override int Count { get; }
(2) 強類型數據表中,實現了疊代接口IEnumerable,實現了實例疊代訪問。類型安全的索引器、Count屬性(與疊代訪問無關)。
強類型數據表中,類型安全的索引器,返回強類型數據行。
public EmployeesRow this[int index]
{
get { return ((EmployeesRow)(this.Rows[index])); }
}
強類型數據表中,Count屬性,返回數據行的數量。
public int Count
{
get { return this.Rows.Count; }
}
強類型數據表中,IEnumerable.GetEnumerator接口方法,
返回IEnumerator接口變數。強類型數據表中的疊代訪問與通過數據行集合疊代訪問表中的數據行本質上是一樣的。
public virtual IEnumerator GetEnumerator()
{
return this.Rows.GetEnumerator();
}
foreach (NorthwindDataSet.CustomersRow rowCustomer in dsNorthwind.Customers) {}
foreach (NorthwindDataSet.CustomersRow rowCustomer in dsNorthwind.Rows) {}
3) 類型安全的方法
(1) NewEmployeesRow,創建一個強類型的新的數據行
public EmployeesRow NewEmployeesRow()
{
return ((EmployeesRow)(this.NewRow()));
}
(2) AddEmployeesRow,在數據行集合中插入一個強類型的新的數據行
public void AddEmployeesRow(EmployeesRow row)
{
this.Rows.Add(row);
}
4) 強類型事件
public event EmployeesRowChangeEventHandler EmployeesRowChanging;
public event EmployeesRowChangeEventHandler EmployeesRowChanged;
public event EmployeesRowChangeEventHandler EmployeesRowDeleting;
public event EmployeesRowChangeEventHandler EmployeesRowDeleted;
public delegate void EmployeesRowChangeEventHandler(object sender, EmployeesRowChangeEvent e);
public class EmployeesRowChangeEvent : global::System.EventArgs
{
private EmployeesRow eventRow;
private global::System.Data.DataRowAction eventAction;
public EmployeesRowChangeEvent(EmployeesRow row,
System.Data.DataRowAction action)
{
this.eventRow = row;
this.eventAction = action;
}
public EmployeesRow Row
{
get { return this.eventRow; }
}
public global::System.Data.DataRowAction Action
{
get { return this.eventAction;}
}
}
1) 通過強類型的屬性顯示行中的每一列的值
(1) 通過DataRow索引器顯示行中的每一列的值(通過集合訪問)
public Object this [DataColumn| int |string columnName]
{ get; set; }
(2) 通過強類型的列屬性顯示行中的每一列的值
沒有任何硬編碼的架構引用,沒有表名或列明的任何字元串文本,而且也不需要按列的位置來索引訪問列。都是通過強類型行對象顯示的強類型列屬性來訪問的。
public string FirstName {
get {
return ((string)(this[this.tableEmployees.FirstNameColumn]));
}
set {
this[this.tableEmployees.FirstNameColumn] = value;
}
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public bool IsBirthDateNull() {
return this.IsNull(this.tableEmployees.BirthDateColumn);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public void SetBirthDateNull() {
this[this.tableEmployees.BirthDateColumn] = global::System.Convert.DBNull;
}
public EmployeesRow[] GetEmployeesRows() {
if ((this.Table.ChildRelations["FK_Employees_Employees"] == null)) {
return new EmployeesRow[0];
}
else {
return ((EmployeesRow[])(base.GetChildRows(this.Table.ChildRelations["FK_Employees_Employees"])));
}
}
(3) 通過方法校驗數據列是否為空。
public bool IsCustomerIDNull() {
return this.IsNull(this.tableOrders.CustomerIDColumn);
}
2) 關係導航
public EmployeesRow EmployeesRowParent {
get {
return ((EmployeesRow)(this.GetParentRow(this.Table.ParentRelations["FK_Employees_Employees"])));
}
set {
this.SetParentRow(value, this.Table.ParentRelations["FK_Employees_Employees"]);
}
}
二.創建強類型數據集的方法
設計器生成 .XSD、.XSC、.XSS 三個檔案,然後用代碼生成工具將.XSD檔案生成強類型數據集。
1) 使用“數據源”視窗
2) 使用“數據集設計器”
3) 基於DataAdapter
三.強類型數據集的優點
通過強類型對象的強類型屬性來進行訪問。可以更加容易和清晰的訪問到它們。通過這些方法和屬性,就算架構發生了改變,代碼也不一定非要更改不可。
應該儘量將非類型化的變數引用強制轉化為強類型的變數引用。(例如使用基類的方法,返回的是非類型化的變數引用,應該強制轉化為強類型的變數引用)
1. 效率
1) 設計(編程)效率
IntelliSense。可以得到強類型在屬性和方法上添加的完整的IntelliSense的支持。
拖放功能。
2) 運行效率
例如:強類型列屬性均通過對象(運行效率最高)來訪問,而不是通過位置索引(運行效率稍次)或字元串名來訪問(運行效率最低)
2. 可維護性
資料庫架構改變:強類型數據集使C#編譯器可以保證找到所有受影響的代碼行。在弱類型數據集,可能漏掉一些地方沒有修改過來,而且直到運行的時候才會發現。
1) 資料庫列的名稱發生改變
例如:將Phone列的名稱改變為PhoneNo。
(1) 重新生成強類型程式集後,引用Phone屬性的每個地方,C#編譯器報錯,
a. 可以在任務窗格中點擊編譯錯誤進行修改成PhoneNo屬性。
b. 做一個全局的查找和替換
c. 使用VS2005的重構工具
(2) 重新生成強類型程式集後,在數據集設計器中Name屬性(在DataTable的列集合中列的名稱string類型)改回為Phone,而保留Source屬性(在DataColumnMapping中的SourceColun的名稱string類型)為PhoneNo不變。
2) 資料庫列的數據類型發生改變
例如:將Phone列的類型由Int類型改變為String類型。
引用Phone列的每個地方,C#編譯器報錯,
3. 類型安全性
DataTable中的數據類型可以做運行時的類型檢查。DataRow類的索引器,簡單的顯示為Object類型的引用,這意味著代碼在設計時可以將任何類型的數值賦予數據列,C#編譯器不可能知道究竟是會成功還是失敗。使用強類型,在設計其間,C#編譯器就可能檢測出類型不兼容的問題。編譯器會防止將不正確的類型賦予某個列。可以確保不會訪問一個不存在的元素。
表數據適配器,提供了一個類型安全的方法用於從資料庫中填充數據集。
生成更新邏輯的方法
1. 手動配置SqlDataAdapter對象生成更新邏輯
2. 使用SqlCommandBuilder對象生成更新邏輯
3. 使用VS[TableAdapte配置嚮導] 生成更新邏輯
4. 使用VS[DataAdapte配置嚮導] 生成更新邏輯