離線資料處理-DataSet物件

iDotNetSpace發表於2008-09-24

1. DataSet物件
l         與SqlDataReader物件對比
SqlDataReader是一種獲取查詢結果快速高效的結構,僅支援向前單向讀取查詢結果,且其中資料為只讀。DataSet支援迴圈來回滾動檢視查詢結果,並支援排序、搜尋、快取修改資料等功能。
l         DataSet物件成員
DataSet包含DataTable物件和DataRelation物件。DataTable物件包括DataRow、DataColumn和Constraint物件。
2. DataTable物件
       DataTable物件包含Columns屬性和Rows屬性分別為DataColumn集合和DataRow集合,它們分別代表結果集的所有列集合與行集合。
l         DataTable中資料的讀取
DataTable中讀取資料要用到DataTable的Rows屬性,其引數指定一個整數代表將要訪問的資料行。
DataRow row=ds.Tables[0].Rows[0];//代表當前行為結果集的第一行
row[0] 或者row[”OrderID”];//代表要訪問當前行的第一列或當前行列名為OrderID的列。使用基於索引的讀取資料的方式比使用基於字串的方式能更快的獲取結果。
基於迴圈的遍歷查詢結果集的方式如下:
Foreach(DataRow row in ds.Table[0].Rows)
       Foreach(DataColumn col in ds.Table[0].Columns)
              Consol.WriteLine(row[col]);
3. 校驗DataTable中的資料
資料庫中提供各種約束以確保資料的有效性,當資料庫的查詢結果儲存到離線物件DataSet中,對DataSet中的資料進行了增、刪、改操作後由SqlDataAdapter提交到資料庫,為確保處理後的資料對資料庫有效,DataTable需要提供與資料庫類似的資料有效性約束機制來保證DataSet中的資料離線處理後同樣遵循資料庫有有效性約束。
l         DataColumn屬性
         ReadOnly
         AllowDBNull
         MaxLength
         Unique(唯一性)
l         DataTable類的Constraints集合
         UniqueConstraint類
       將DataColumn的Unique屬性設定為True,也是定義該列在DataTable中的唯一性約束;顯示定義唯一性約束是將新建立的UniqueConstraint物件新增到Constraints集合中。
         PrimaryKey屬性
DataTable類通過PrimaryKey屬性定義該表的主鍵,PrimaryKey屬性包含DataColumn物件陣列。
         ForeignKeyConstraint類
通常可以通過在DataSet內的兩DataTable物件之間建立DataRealation可以隱式的建立外來鍵約束
l         程式碼中建立DataTable物件
         建立DataTable物件
DataTable dt=new DataTable(“TableName”) ;//建立DataTable物件並同時命名
         向DataSet的Tables集合中新增DataTable
DataTable dt=ds.Tables.Add(“Orders”);//新建DataTable並新增到DataSet中
DataTableMapping dtm = new DataTableMapping();
dtm = da.TableMappings.Add("", "Orders");//第一個引數為空,第二個引數與定義時一致
DataColumnMapping[]columnMaps;
columnMaps = new DataColumnMapping[]
            {
                new DataColumnMapping("OrderID","訂單號"),
                            …...
                     }
dtm.ColumnMappings.AddRange(columnMaps);
DataColum col=dt.columns.add(“訂單號”,typeof(int))
//DataTable中新增列,列名稱與columnMaps中定義一致
……//設定col的屬性
da.Fill(dt);
DataTable的DataSet屬性確定該DataTable是否屬於某個DataSet,如果該DataTable是屬於某個DataSet的Tables集合,則返回該DataSet,否則返回Null。一個DataTablek至多隻能存在於一個DataSet中,如果想將一個DataTable新增到多個DataSet中,必須使用Copy或Clone方法。
         提取架構資訊
預設情況下,DataAdapter類的Fill方法返回的DataSet和DataTable不包含架構資訊,如果DataTable中不包含某列,DataAdapter會自動新增這些列到DataTable中。DataAdapter類可以通過MissingSchemaAction屬性或FillSchema方法來返回帶有架構資訊的結果集。由於返回帶有架構資訊的結果集會帶來很大的系統消耗,一般情況可以用程式碼提供DataTable和DataSet的架構,而避免使用上述兩種方式。
l         設定DataTable約束
         設定主鍵 PrimaryKey屬性
DtataTable主鍵PrimaryKey屬性為一個DataColumn物件的陣列。
DataTable tbl=ds.Tables.add(“Customers”);
tbl.Columns.Add(“OrderID”,typeof(int));
tbl.Columns.Add(“ProductID”,typeof(int));
tbl.PrimaryKey=new DataColumn[]{
                            tbl.Columns[“OrderID”],
                            tbl.Columns[“ProductID”]};
         新增其它約束
DataTable類的Constraints集合有一個過載的Add方法,可用於新增新的主鍵值、唯一鍵和外來鍵約束。
顯式建立唯一性和外來鍵約束的方法如下:
DataTable.Constraints.Add(New UniqueConstraint(…));
DataTable.Constraints.Add(New ForeignKeyConstraint(…));
隱式建立主鍵和唯一性約束程式碼如下:
DataTable.Constraints.Add(“PK_OrderID”,Orders.Columns[“OrderID”],true);
DataTable.Constraints.Add(“UK_CustomerID”,Orders.Columns[“CustomerID”],false);
//第一個引數代表所建約束的名稱,第二個引數是對應新增約束的列,第三個引數true代表主鍵約束、false代表唯一性約束。
隱式建立外來鍵約束
DataTable.Constraints.Add(“FK_CustomerID”,tblCustomers.Columns[“CustomerID”]
,tblOrders.Columns[“CustomerID”]);
//第一個引數代表約束名稱,第二個引數代表父表的DataColumn,第三個陣列代表子表中的DataColunm。
l         處理自動增量列
如果資料庫中使用自動增量,Ado.Net的自動增量特性有助於在將這些新行提交到資料庫之前,使掛起插入一致。
DataColumn col=tbl.Columns.Add(“OrderID”,typeof(int));
col.AutoIncrement=true;
col.AutoIncrementSeed=-1;
col.AutoIncrementStep=-1;
Ado.Net只是根據DataTable中的資料來生成新的自動增量值,它並不代表資料庫中要生成的下一自動增量值。因此相對於資料庫中的新行,DataTable中的自動增量值只是一個佔位符,不能直接提交給資料庫。
l         DataTable中新增基於表示式的列
資料庫會避免儲存能夠從資料庫中的已有資料中推匯出的資料,SQL語言中支援查詢結果中包含經過計算的列。
Select UnitPrice ,Quantity, UnitPrice*Quantity as ItemTotal from [Order Details]
以上查詢語句的查詢結果儲存到DataTable後,如果UnitPrice或Quantity有更改,則DataTable中ItemTotal的值不會改變。
Ado.Net支援建立基於表示式的DataColumn物件,可以不在查詢中包含計算後的表示式,而是將一個DataColumn的Expression屬性設定為一個表示式,這樣表示式的值就會隨計算項的值變化而變化。
DataTable tbl=ds.Tables.Add(“Orders”);
tbl.Columns.Add(“Quantity”,typeof(int));
tbl.Columns.Add(“UnitPrice”,typeof(Decimal));
tbl.Columns.Add(“ItemTotal”,typeof(Decimal),”Quantity*UnitPrice”);
4. 修改DataTable中的資料
l         新增新的DataRow
         DataRowCollection類的Add方法
DataTable類的NewRow方法返回新的DataRow物件,設定Item屬性填充各列,然後呼叫DataRowCollection的Add方法將新行新增到DataTable中。
DataTable tbl=new DataTable(“Customers”);
tbl.Columns.Add(“CustomerID”,typeof(string));
tbl.Columns.Add(“CompanyName”,typeof(string));
DataRow row=tbl.NewRow();
row[“CustomerID”]=”NewCo”;
row[“CompanyName”]=”New Customer”
tbl.Rows.Add(row);
DataRowCollection的過載Add方法
tbl.Rows.Add(“NewCo”,”New Customer”);//引數對應DataTable各列的值
以上兩種Add方法新增新行的RowState為Added。
         DataTable類的LoadDataRow方法
tbl.LoadDataRow(New Object(){“NewCo”,”New Customer”},False);
第一個引數為DataRow各列值清單,第二個引數為False時將會設定DataRow的RowState為Added;如果為True則DataRow的RowState為Unchanged。
l         修改現有行
         利用DataRow的Item屬性
修改DataRow物件時,先利用Rows集合的Find方法找到要修改的行,然後利用其Item屬性重新設定各列的值即可。
DataRow row =tbl.Rows.Find(“NewCo”);
If(row==null)
//未找到相關行
Else
       row[“CompanyName”]=”New Value”
End if
         使用DataRow類的BeginEdit方法和EndEdit方法
呼叫BeginEdit和EndEdit方法可以緩衝對資料行的修改,呼叫EndEdit方法儲存對行的更改,如果確定有用儲存更改,可以呼叫CancelEdit來撤銷更改,該行將返回到BeginEdit時的狀態。
DataRow row =tbl.Rows.Find(“NewCo”);
If(row==null)
//未找到相關行
Else{
       row.BeginEdit();
       row[“CompanyName”]=”New Value”
   row.EndEdit();
End if
         使用DataRow的ItemArray屬性
使用ItemArray屬性可以獲取修改整個DataRow物件中的資料,每個Item對應DataRow中的一列,可以完成一次更新一行中的多個列值。
DataRow row=tbl.Rows.Find(“NewCo”);
row.ItemArray=new object[]{null,”New Value”};//null代表對應的列不用更改
         處理DataRow中的Null值
DataRow類的IsNull方法可以檢視某一列是否為Null;IsNull方法接受一個列名稱或該列索引的整數或一個DataColumn物件為引數
如果某列的值要設定為Null值,應該使用DBNull類的Value屬性。
row[“CompanyName”]=DBNull.Value;
l         刪除DataRow
         Delete方法
刪除資料行只用呼叫DataRow的Delete方法即可,但此方法並沒有將資料行從DataTable中刪除,而是由Ado.Net將該行標記為掛起刪除,以便利用DataAdapter類將掛起刪除提交給資料庫。如果從DataTable中完全刪除該行,那麼在提交DataSet的掛起更改時,將不會從資料庫中刪除相應的行。
         移除DataRow
DataRowCollection類的Remove或RemoveAt方法實現從DataTable中完全移除一個資料行,而不是將資料行標記為掛起更改
DataRow row=tbl.Rows.Find(“NewCo”);
tbl.Rows.Remove(row);
//or
tbl.Rows.RemoveAt(tbl.Rows.IndexOf(row));
另外,DataSet和DataTable類各具有一個Clear方法,可以清除其全部資料物件,但保留內部結構。
l         DataRow的RowState屬性
DataSet可以進行資料快取更改,在向資料庫提交這些更改前,快取更改不會影響到資料庫的資料。資料庫的更改包括插入、更新、刪除,DataRow的RowState屬性將記錄DataSet的資料更改資訊。RowState屬性值為DataRowState列舉中的值,列表如下:
常數 值 說明
Unchanged 2 該行未包含任何更改
Detached 1 該行不是DataTabler 成員
Added 4 該行已經被新增到DataTable,但還不存在於資料庫中
Modified 16 該行包含掛起更改
Deleted 8 該行包含掛起刪除

SqlDataAdapter類在成功提交儲存在DataSet中的掛起更改後,呼叫DataRow的AcceptChanges方法,清除儲存在DataRow中的掛起更改。
DataRow類的RejectChanges方法,用來撤銷儲存在DataRow中的更改。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-462853/,如需轉載,請註明出處,否則將追究法律責任。

相關文章