DataSet物件
DataSet物件可以用來儲存從資料庫查詢到的資料結果,由於它在獲得資料或更新資料後立即與資料庫斷開,所以程式設計師能用此高效地訪問和運算元據庫。
並且,由於DataSet物件具有離線訪問資料庫的特性,所以它更能用來接收海量的資料資訊。
DataSet物件概述
DataSet是ADO.NET中用來訪問資料庫的物件。
由於其在訪問資料庫前不知道資料庫裡表的結構,所以在其內部,用動態XML的格式來存放資料。這種設計使DataSet能訪問不同資料來源的資料。
DataSet物件本身不同資料庫發生關係,而是通過DataAdapter物件從資料庫裡獲取資料並把修改後的資料更新到資料庫。
在DataAdapter的講述裡,就已經可以看出,在同資料庫建立連線後,程式設計師可以通過DataApater物件填充(Fill)或更新(Update)DataSet物件。
.NET的這種設計,很好地符合了物件導向思想裡低耦合、物件功能唯一的優勢。
如果讓DataSet物件能直接連到資料庫,那麼DataSet物件的設計勢必只能是針對特定資料庫,通用性就非常差,這樣對DataSet的動態擴充套件非常不利。
由於DataSet獨立於資料來源,DataSet可以包含應用程式本地的資料,也可以包含來自多個資料來源的資料。
與現有資料來源的互動通過DataAdapter來控制。
DataSet物件常和DataAdapter物件配合使用。
通過DataAdapter物件,向DataSet中填充資料的一般過程是:
(1)建立DataAdapter和DataSet物件。
(2)使用DataAdapter物件,為DataSet產生一個或多個DataTable物件。
(3)DataAdapter物件將從資料來源中取出的資料填充到DataTable中的DataRow物件裡,然後將該DataRow物件追加到DataTable物件的Rows集合中。
(4)重複第(2)步,直到資料來源中所有資料都已填充到DataTable裡。
(5)將第(2)步產生的DataTable物件加入DataSet裡。
而使用DataSet,將程式裡修改後的資料更新到資料來源的過程是:
(1)建立待操作DataSet物件的副本,以免因誤操作而造成資料損壞。
(2)對DataSet的資料行(如DataTable裡的DataRow物件)進行插入、刪除或更改操作,此時的操作不能影響到資料庫中。
(3)呼叫DataAdapter的Update方法,把DataSet中修改的資料更新到資料來源中。
DataSet物件模型
從前面的講述中可以看出,DataSet物件主要用來儲存從資料庫得到的資料結果集。
為了更好地對應資料庫裡資料表和表之間的聯絡,DataSet物件包含了DataTable和DataRelation型別的物件。
其中,DataTable用來儲存一張表裡的資料,其中的DataRows物件就用來表示表的欄位結構以及表裡的一條資料。
另外,DataTable中的DataView物件用來產生和對應資料檢視。
而DataRelation型別的物件則用來儲存DataTable之間的約束關係。
DataTable和DataRelation物件都可以用物件的集合(Collection)物件類管理。
由此可以看出,DataSet中的方法和物件與關聯式資料庫模型中的方法和物件一致,DataSet物件可以看作是資料庫在應用程式碼裡的對映,通過對DataSet物件的訪問,可以完成對實際資料庫的操作。
DataSet的物件模型如圖所示。
DataSet物件模型中的各重要元件說明如下。
1.DataRelationCollection和DataRelation
DataRelation物件用來描述DataSet裡各表之間的諸如主鍵和外來鍵的關係,它使一個DataTable中的行與另一個DataTable中的行相關聯,也可以標識DataSet中兩個表的匹配列。
DataRelationCollection是DataRelation物件的集合,用於描述整個DataSet物件裡資料表之間的關係。
2.ExtendedProperties
DataSet、DataTable和DataColumn全部具有ExtendedProperties屬性。可以在其中加入自定義資訊,例如用於生成結果集的SQL語句或生成資料的時間。
3.DataTableCollection和DataTable
在DataSet裡,用DataTable物件來對映資料庫裡的表,而DataTableCollection用來管理DataSet下的所有DatabTable。
DataTable具有以下常用屬性。
(1)TableName:用來獲取或設定DataTable的名稱。
(2)DataSet:用來表示該DataTable從屬於哪個DataSet。
(3)Rows:用來表示該DataTable的DataRow物件的集合,也就是對應著相應資料表裡的所用記錄。
程式設計師能通過此屬性,依次訪問DataTable裡的每條記錄。該屬性有如下方法。
Add:把DataTable的AddRow方法建立的行追加到末尾。
InsertAt:把DataTable的AddRow方法建立的行追加到索引號指定的位置。
Remove:刪除指定的DataRow物件,並從物理上把資料來源裡的對應資料刪除。
RemoveAt:根據索引號,直接刪除資料。
(4)Columns:用來表示該DataTable的DataColumn物件的集合,通過此屬性,能依次訪問DataTable裡的每個欄位。
DataTable具有以下常用方法。
DataRow NewRow()方法:該方法用來為當前的DataTable增加一個新行,返回表示行記錄的DataRow物件,但該方法不會把建立好的DataRow新增到DataRows集合中,而是需要通過呼叫DataTable物件Rows屬性的Add方法,才能完成新增動作。
DataRow [] Select()方法:該方法執行後,會返回一個DataRow物件組成的陣列。
void Merge(DataTable table)方法:該方法能把引數中的DataTable和本DataTable合併。
void Load(DataReader reader)方法:該方法通過引數裡的IdataReader物件,把對應資料來源裡的資料裝載到DataTable裡,以便後繼操作。
void Clear()方法:該方法用來清除DataTable裡的資料,通常在獲取資料前呼叫。
void Reset()方法:該方法用宋重置DataTabl物件。
DataColumn和DataRow物件
在DataTable裡,用DataColumn物件來描述對應資料表的欄位,用DataRow物件來描述對應資料庫的記錄。
值得注意的是,DataTable物件一般不對錶的結構進行修改,所以一般只通過Column物件讀列。
例如,通過DataTable.Table[”TableName"].Column[columnName]來獲取列名。
DataColumn物件的常用屬性如下。
Caption屬性:用來獲取和設定列的標題。
ColumnName屬性:用來描述該DataColumn在DataColumnCollection中的名字。
DataType屬性:用來描述儲存在該列中資料的型別。
在DataTable裡,用DataRow物件來描述對應資料庫的記錄。
DataRow物件和DataTable裡的Rows屬性相似,都用來描述DataTable裡的記錄。
同ADO版本中的同類物件不同的是,ADO.NET下的DataRow有“原始資料”和“已經更新的資料”之分,並且,DataRow中的修改後的資料是不能即時體現到資料庫中的,只有呼叫DataSet的Update方法,才能更新資料。
DataRow物件的重要屬性有RowState屬性,用來表示該DataRow是否被修改和修改方式。RowState屬性可以取的值有Added、Deleted、Modified或Unchanged。
而DataRow物件有以下重要方法。
void AcceptChanges()方法:該方法用來向資料庫提交上次執行AcceptChanges方法後對該行的所有修改。
void Delete()方法:該方法用來刪除當前的DataRow物件。
設定當前DataRow物件的RowState屬性的方法:此類方法有:
void SetAdded( ) ;
void SetModified();
分別用來把DataRow物件設定成Added和Modified。
void AcceptChanges()方法:該方法用來向資料庫提交上次執行AcceptChanges方法後對該行的所有修改。
void BeginEdit()方法:該方法用來對DataRow物件開始編輯操作。
void cancelEdit()方法:該方法用來取消對當前DataRow物件的編輯操作。
void EndEdit()方法:該方法用來終止對當前DataRow物件的編輯操作。
下面的程式碼講述瞭如何綜合地使用DataTable、DataColumn和DataRow物件進行資料庫操作。
private void DemonstrateRowBeginEdit( ) { //建立DataTable物件 DataTable table=new DataTable("table1"); //建立DataColumn物件,並設定其屬性為Int32型別 DataColumn column=new DataColumn("col1", Type.GetType(" System.Int32" )); // 新增Column到dataTable中 table.Columns.Add(column); //使用for迴圈,建立5個DataRow物件並新增到DataTable中 DataRow newRow; for(int i=0; i<5; i++) { // RowChanged event will occur for every addition newRow=table.NewRow(); newRow[0]=i; table.Rows.Add(newRow); } //使用dataTable的AcceptChanges方法,將更改提交到資料庫中 table.AcceptChanges(); //開始操作DataRow中的每個物件 foreach(DataRow row in table.Rows) { //使用BeginEdit方法開始操作 row.BeginEdit(); row[0]=(int) row[0]+10; } table.Rows[0].BeginEdit(); table.Rows[1].BeginEdit(); table.Rows[0][0]=100; table.Rows[1][0]=100; try { //終止對DataRow物件進行操作 table.Rows[0].EndEdit(); table.Rows[1].EndEdit(); } catch(Exception e) { //出錯處理 Console.WriteLine(" Exception of type {0} occurred. " , e.GetType() ); } }
上述程式碼的主要業務邏輯如下:
(1)建立DataTable和DataColumn型別的物件,並把DataColumn物件的資料型別設定成System.Int32。
也就是說,使用該DataColumn物件可以對應地接收int型別的欄位資料。
(2)把DataColumn物件新增到DataTable中。
(3)依次建立5個DaaRow物件,同時通過for迴圈給其賦值。完成賦值後,將這5個DataRow物件新增到DataTable中。
(4)使用AcceptChanges方法,實現DataColumn和DataRow物件的更新。
(5)使用BeginEdit方法,開始編輯DataRow物件,使用EndEdit方法來表示編輯結束。
使用DataTable、DataColumn和DmaRow物件訪問資料的一般方式有以下幾種。
(1)使用Table名和Table索引來訪問DataTable。為了提高程式碼的可讀性,推薦使用Table名的方式來訪問Table。程式碼如下:
DataSet ds=new DataSet(); DataTable dt=new DataTble(" myTableName"); //向DataSet的Table裡新增一個dataTable ds.Tables.Add(dt); //訪問dataTable //1 通過表名訪問,推薦使用 ds.Tables["myTableName"].NewRow(); //2 通過索引訪問,索引值從0開始,不推薦使用 ds.Tables[0].NewRow();
(2)使用Rows屬性訪問資料記錄,例如:
foreach(DataRow row in table.Rows) { Row[0]=(int) row[0]+10; }
(3)使用Rows屬性,訪問指定行的指定欄位,例如:
//首先為DataTable物件建立一個資料列 DataTable table=new DataTable("table1"); DataColumn column=new DataColumn(" col1", Type.GetType("System.Int32")); table.Columns.Add(column); // 其次為DataTable新增行資料 newRow=table.NewRow(); newRow[0]=10; table.Rows.Add(newRow); //設定索引行是0,列名是col1的資料 table.Rows[0]["col1"]=100; //設定索引行是0,索引列是0的資料,這種做法不推薦 //table.Rows[0][0]=100;
(4)綜合使用DataRow和DataColumn物件訪問DataTable內的資料。
從以下程式碼可以看出,DataTable物件中的Rows屬性對應於它的DataRow物件,而Columns屬性對應於DataColumn。
foreach(DataRow dr in dt.Rows ) { foreach(DataColumn dc in dt.Columns ) { //用陣列訪問資料 dr[dc]=100; } }