DataSet對象可以用來存儲從數據庫查詢到的數據結果,由於它在獲得數據或更新數據後立即與數據庫斷開,所以程序員能用此高效地訪問和操作數據庫。並且,由於DataSet對象具有離線訪問數據庫的特性,所以它更能用來接收海量的數據信息。
1 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中修改的數據更新到數據源中。
2 DataSet對象模型
從前面的講述中可以看出,DataSet對象主要用來存儲從數據庫得到的數據結果集。爲了更好地對應數據庫裏數據表和表之間的聯繫,DataSet對象包含了DataTable和DataRelation類型的對象。
其中,DataTable用來存儲一張表裏的數據,其中的 DataRows對象就用來表示表的字段結構以及表裏的一條數據。另外,DataTable中的DataView對象用來產生和對應數據視圖。而 DataRelation類型的對象則用來存儲DataTable之間的約束關係。DataTable和DataRelation對象都可以用對象的集合 (Collection)對象類管理。
由此可以看出,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 (IDataReader reader)方法:該方法通過參數裏的IdataReader對象,把對應數據源裏的數據裝載到DataTable裏,以便後繼操作。
Ü void Clear ()方法:該方法用來清除DataTable裏的數據,通常在獲取數據前調用。
Ü void Reset()方法:該方法用來重置DataTabl對象。
3 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 RejectChanges()方法:該方法用來撤銷自上次執行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個DataRow對象,同時通過for循環給其賦值。完成賦值後,將這5個DataRow對象添加到DataTable中。
(4) 使用AcceptChanges方法,實現DataColumn和DataRow對象的更新。
(5) 使用BeginEdit方法,開始編輯DataRow對象,使用EndEdit方法來表示編輯結束。
使用DataTable、DataColumn和DataRow對象訪問數據的一般方式有以下幾種。
(1) 使用Table名和Table索引來訪問DataTable。爲了提高代碼的可讀性,推薦使用Table名的方式來訪問Table。代碼如下:
DataSet ds = new DataSet();
DataTable dt = new DataTable("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;
}
}
4 使用DataSet對象訪問數據庫
當對DataSet對象進行操作時,DataSet對象會產生副本,所以對DataSet裏的數據進行編輯操作不會直接對數據庫產生影響,而是將DataRow的狀態設置爲added、deleted或changed,最終的更新數據源動作將通過 DataAdapter對象的update方法來完成。
DataSet對象的常用方法如下。
Ü void AcceptChanges():該方法用來提交DataSet裏的數據變化。
Ü void clear():該方法用來清空DataSet裏的內容。
Ü DataSet copy():該方法把DataSet的內容複製到其他DataSet中。
Ü DataSet GetChanges():該方法用來獲得在DataSet裏已經被更改後的數據行,並把這些行填充到Dataset裏返回。
Ü bool HasChanges():如果DataSet在創建後或執行AcceptChanges後,其中的數據沒有發生變化,返回True,否則返回False。
Ü void RejectChanges():該方法撤銷DataSet自從創建或調用AcceptChanges方法後的所有變化。
DataSet對象一般是和DataAdapter 對象配合使用。下面的代碼演示瞭如何綜合使用DataSet和DataAdapter 對象訪問數據庫。
//省略獲得連接對象的代碼
…
//創建DataAdatper
string sql = " select * from user";
SqlDataAdapter sda = new SqlDataAdapter(sql,conn)
//創建並填充DataSet
DataSet ds = new DataSet();
sda.fill(ds,”user”);
//給DataSet創建一個副本,操作對副本進行,以免因誤操作而破壞數據
DataSet dsCopy = ds.Copy();
DataTable dt = ds.Table["user"];
//對DataTable中的DataRow和DataColumn對象進行操作
…
//最後將更新提交到數據庫中
sda.update(ds, "user");
上述代碼的主要業務流程如下。
(1) 創建DataAdapter和DataSet對象,並用DataAdapter的SQL語句生成的表填充到DataSet的DataTable中。
(2) 使用DataTable對錶進行操作,例如做增、刪、改等動作。
(3) 使用DataAdapter的update語句將更新後的數據提交到數據庫中。
另外,上述代碼在操作DataSet前,爲DataSet創建了一個副本,用來避免誤操作。
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/kybd2006/archive/2007/07/12/1687028.aspx