DataTable快取資料操作

iDotNetSpace發表於2009-01-05
(由於書上的程式碼全是用C#寫的,轉換為VB.NET實在麻煩,以後就不轉換了,見諒)
五、操縱dataset
在DataSet中DataRow是其所有資料的基本存放位置,它主要是由一個值陣列組成,代表DataTable單獨一行。
DataRow中主要包括一下幾種資訊:1、行中每一列的當前值,2、行中每一列的原始值,3、行狀態,4、父行與子行間的連結

初始化一個DataRow:
DataTable dataTable=dataSet.Tables[0];
DataRow newRow=dataTable.NewRow(); //用dataTable生成DataRow可以利用dataTable裡面的模式
dataTable.Rows.Add(newRow);

刪除行:
DataTable.Rows.Remove(行例項);
DataTable.Rows.RemoveAt(行號);
DataRow.Delete(); //行自身移除

讀寫DataRow的值:
row["列名"],row[列號]均可引用其中的一個屬性
DataColumn a=dataTable.Columns("列名"); //可以獲得一個列

對行進行批處理更改:
BeginEdit()開始更改,EndEdit()結束更改,同時將更改結果寫入DataSet,CancelEdit(),取消更改
例如:
row.BeginEdit();
對row進行更改
row.EndEdit();

將資料批量載入到DataTable
dataTable.BeginLoadData();
dataTable.LoadDataRow(row1,false); //第二個引數為true時,呼叫dataTable.AcceptChanges()時接受更改,為false直接新增
……
dataTable.EndLoadData();
使用這種資料載入方式可以在資料載入期間遮蔽所有的資料約束,索引也不會予以維護,極大的加快了資料載入速度

行的版本:
current:當前值
default:根據操作的不同決定行的default值
original:最後一次呼叫AcceptChanges()之後的值
proposed:呼叫AcceptChanges()之前被更改的值
例如要獲得行的original值:
String ldString=row("FirstName",DataRowVersion.original);

行的狀態:
row.RowState獲得行的狀態,例如刪除後變成Deleted,資料儲存更新後變為unchanged

六、DataSet導航
在ADO.NET中每個表都保持其相對獨立性,允許在行級上導航不同表之間的相關行(向下導航到子行,向上導航的父行)
如DataRow[] invoiceRows=custRow.GetChildRows("Customer_invoice"); //通過關係導航到子行

七、DataView
DataView就時資料檢視,為資料庫結構提供了外模式的實現。
同時DataView也可以為窗體控制元件和Web控制元件提供資料繫結功能,在每一個DataTable中內建了一個DataView為:DataTable.DefaultView();

建立DataView
DataView sortedView=new DataView(dataTable);

對DataView進行排序
dataTable.DefaultView.sort="lastName";
dataTable.DefaultView.sort="lastName,FirstName DESC";

對DataView進行篩選:
1、通過對其中的RowFilter屬性設定可以實現篩選
dataTable.DefaultView.RowFilter="Vendor='Rawlings'";
不過篩選表示式只能設定成比較簡單的表示式,功能有限,不過可以滿足基本的要求。
同樣在DataTable裡面也可以進行簡單的搜尋,返回一個DataRow陣列,例:
DataRow[] compoundRows=dataTable.select("Vendor='wilson' AND price>20.00)
2、通過RowState來篩選
dataTable.DefaultView.RowStateFilter="DataViewRowState.originalRows"可以篩選出符合要求狀態的row

對DataView進行搜尋:
相對於DataView使用RowFilter進行篩選得到一個矩形資料集,使用Find、FindRows可以更準確的查詢到與特定鍵相匹配的行
搜尋的時候必須首先設定DataView的sort屬性:
int found=dataTable.DefaultView.Find("wilson"); //獲得行的位置
DataRowView[] rows=dataTable.DefaultView.FindRows("Rawlings") //過得一個row陣列

八、更新DB
在DataSet中,每一個DataTable對應著一個DataAdapter,DataAdapter.Update()時,DataTable自動更新。
更新的時候可以使用CommandBuilder自動根據DataSet的變化生成更新的SQL命令
SqlCommandBuilder bldr=new SqlCommandBuilder(dataAdapter);
dataAdapter.Update(custTable);
不過Update接受DataSet引數並不更新DataSet而是更新DataSet中的一個叫"Table"的表
使用CommandBuilder進行更新的時候要注意一下幾點:
1、SelectCommand必須有效
2、必須有主碼
3、若SelectCommand填充DataTable後架構發生改變,應該在Update()之前呼叫CommandBuilder.RefreshSchema();
4、更新DB時不受關係、約束或者DataSet中其他表的影響
雖然使用CommandBuilder比較方便,不用自己寫更新命令,但自動生成的命令效能不高,這時可以考慮自己編寫儲存過程或直接使用帶引數的sql語句,例如:
String insQry="Insert into Customer(CustomerID) Values (@Customer)";
SqlCommand insCmd=conn.CreateCommand();
insCmd.CommandText=insQry;
SqlParameterCollection insParams=insCmd.Parameters;
insParams.Add("@CustomerID",SqlDbType.UniqueIdentifier,0,"CustomerID");
dataAdapter.InsertCommand=insCmd;
dataAdapter.Update();
在dataAdapter.Update()更新時還可以控制更新的範圍:
dataAdapter.Update(invTable.GetChanges(DataRowState.Deleted); //只更新被刪除的部分

九、事務
tx=conn.BeginTransaction(IsolationLevel.Serializable);
invDA.SelectCommand.Transaction=tx;
事務操作
tx.Commit();提交 //tx.Rollback();事務回滾

十、資料繫結
簡單版本:(對文字框、標籤等)
{Controls}.DataBindings.Add("{Property}",{dataSource},"{dataMember}");
其中Property為待繫結的屬性,dataSource為DataView或DataTable,dataMember為dataSource其中的某個屬性

複雜版本:(對ListBox、ComboBox等)
要分別設定各個屬性實現繫結:
DataSource=支援IList的一個物件(DataTable或DataView)
DisplayMember:待顯示的DataSource中的一個屬性
ValueMember:確定在DataSource中引用哪一個資料行,即實現與DisplayMember的名值對應

DataGrid繫結:
1、可以設定DataSource屬性實現靜態繫結
2、可以使用SetDataBinding函式實現動態繫結

同時DataGrid支援主控/詳細表顯示
masterGrid.setDataBinding(customerTable,"");
detailGrid.setDataBinding(customerTable,"Customer_Invoices") //第二個屬性要設定成關係約束
這樣在主表中選擇一行,在子表中就根據主錶行中外碼在子表中找到相應行

繫結之後,繫結項中就有一個CurrencyManager屬性實現遊標功能
BindingContext[CustomerTable]返回一個CurrencyManager物件,其中的Position屬性可以更改,實現遊標的移動。

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

相關文章