摘要:在ADO.NET提供的數據訪問控件中,DataView具有功能強大的數據處理功能。本文就DataView的數據排序、數據篩選、數據搜索、數據修改等功能實現技巧進行探討。
關鍵詞:vb.net;數據源;DataView控件
中圖法分類號:TP311 文獻標識碼:A 文章編號:1009-3044(2008)08-10ppp-0c
1 前言
隨著計算機功能不斷增強,計算機領域不斷擴大,在計算機上運行的應用軟件功能也在增強、復雜化。為了完成龐大的計算機軟件功能,計算機軟件開發和應用中不得不涉及到數據庫處理技術。在軟件開發和應用中,經常需要對數據庫中數據進行頻繁訪問和處理。在訪問大型數據庫時,怎樣才能得到有效的數據,并能對數據進行有效處理,提高程序效率?在.NET平臺下的ADO.NET數據處理控件中,能充分使用DataView控件對數據處理技巧,將在軟件開發中,大大提高數據處理功能,從而提高程序效率。
2 DataView的使用技巧
2.1 數據排序功能
在.NET中實現組件數據綁定時,常常需要對數據進行排序。如果數據源使用是DataView控件,則可很容易實現對數據進行排序。
通過DataView控件來排序數據源中的數據,常有方法有:
2.1.1 用DataView對象的Sort屬性排序
可在建立DataView對象之后,再配置其Sort屬性以便決定要如何排序數據。Sort屬性的配置方式與Sort參數的配置方式完全相同。
如圖1,下面主要代碼示范如何在執行階段動態配置DataView的Sort屬性,以便讓用戶能夠通過一或兩個字段來動態排序數據。
Dim SortExpr As String
If ComboBoxSortColumn1.SelectedIndex > -1 Then
SortExpr = ComboBoxSortColumn1.SelectedItem.ToString _
IIf(RadioButton1.Checked, \" ASC\", \" DESC\")
If ComboBoxSortColumn2.SelectedIndex > -1 Then
SortExpr = \", \" ComboBoxSortColumn2.SelectedItem.ToString _ IIf(RadioButton3.Checked, \" ASC\", \" DESC\")
End If
DataView1.Sort = SortExpr
Else
MessageBox.Show(\"您至少必須選擇排序的第一個字段\")
End If

圖1 DataView對象的Sort屬性排序
2.1.2 用DataView對象的Sort參數排序
可使用DataView對象的Sort參數來決定要根據一個或多個字段來排序數據。可以在字段名稱之后加上關鍵詞ASC(升序)或DESC(降序),以便決定要根據此字段是遞增還是遞減排序,默認為遞增排序。如果要根據多個字段排序數據,請在各字段使用逗號(,)來加以分隔。
2.1.3 用DataView對象的ApplyDefaultSort屬性排序
可以配置DataView對象的ApplyDefaultSort屬性,以便決定是否根據主鍵來排序數據。當將ApplyDefaultSort屬性設為True,表示要根據主鍵來排序數據;當 ApplyDefaultSort屬性設為False(此為默認值),表示不根據主鍵來排序數據。
注意:只有在Sort屬性為Null引用或空字符串,以及當表定義主鍵時,才會套用ApplyDefaultSort屬性的配置。
2.2 數據篩選功能
在.NET中實現組件數據綁定時,有時只需要綁定的部分數據。如果數據源使用是DataView控件,則可很容易實現對數據進行篩選。
2.2.1 用DataView對象的RowFilter參數篩選
可使用DataView對象的RowFilter參數來設定篩選數據的表達式。由于表達式內容比較復雜,請查閱相關資料,這里不再闡述。
2.2.2 用DataView對象的RowFilter屬性篩選
可在建立DataView對象之后再配置其RowFilter屬性以便決定要如何篩選數據。RowFilter屬性的配置方式與RowFilter參數的表達式配置方式完全相同。
如圖2,下面主要代碼示范如何在執行階段動態配置DataView的RowFilter屬性,以便讓用戶能夠通過一或兩個字段來動態篩選數據。
Dim RowFilterExpr As String = \"\"
If ComboBoxDepartment.SelectedIndex > -1 Then
RowFilterExpr = \"部門 = '\" ComboBoxDepartment.SelectedItem.ToString() \"'\"
End If
If ComboBoxGender.SelectedIndex > -1 Then
If RowFilterExpr <> \"\" Then
RowFilterExpr = \" AND \"
End If
RowFilterExpr = \"性別 = '\" ComboBoxGender.SelectedItem.ToString() \"'\"
End If
If RowFilterExpr = \"\" Then
MessageBox.Show(\"您沒有設定任何篩選條件\")
Exit Sub
End If
DataView1.RowFilter = RowFilterExpr
txtRowCount.Text = DataView1.Count.ToString

圖2 DataView對象的RowFilter屬性篩選
2.2.3 用DataView對象的RowState參數來篩選
在建立DataView對象時,可使用RowState參數來設定記錄狀態的篩選條件。RowState參數的類型是列舉類型DataViewRowState,如表1,列出了DataViewRowState的所有成員。
表1DataViewRowState的枚舉值

例如:如果將RowState參數設為DataViewRowState.Deleted,則DataView會公開所有Deleted記錄的Original記錄版本,因為沒有Current記錄版本。可以使用DataRowView的RowVersion屬性,來判斷公開的記錄版本為何。
2.2.4 用DataView對象的RowStateFilter屬性來篩選
可以在建立DataView對象之后,再配置其RowStateFilter屬性以便決定要如何篩選記錄版本。RowStateFilter屬性的配置方式與RowState參數的配置方式相同。
2.3 數據搜索功能
2.3.1 使用DataView的Find方法來搜索記錄
Find方法提供表2所示的兩個重載版本。
表2 Find方法的重載版本

Find方法使用記錄的排序鍵值來搜索記錄,那么,在調用Find方法之前,務必先將ApplyDefaultSort屬性設定為True或是利用Sort屬性來設定排序順序,否則將會拋出異常。例如,如果搜索“姓名”字段為“章立民”的記錄,必須使用“姓名”字段來排序數據,然后才能調用Find方法進行搜索,代碼寫法如下:
DataView1.Sort=”姓名”
Dim rowIndex AS Integer=DataView1.Find(“章立民”)
If rowIndex=-1 Then
MessageBox.Show(“找不到您所搜索的姓名”)
Else
MessageBox.Show(DataView1(rowIndex)(“姓名”) DataView1(rowIndex)(“當前工資”).ToString())
End If
以上的代碼中,Find方法會返回所搜索到記錄的索引。如果有多條記錄符合搜索條件,則只會返回第一條符合搜索條件的記錄的索引。如果找不到任何符合條件的記錄,則Find方法會返回-1。
Find方法在搜索數據值時,會根據源DataTable的CaseSensitive屬性來決定是否考慮大小寫。搜索值必須完全符合現有的排序索引鍵值,才能返回結果。
注意:如果使用單一字段來排序數據,請使用第一個版本的Find方法來搜索排序鍵值,并將單一值傳遞給它。然而,如果使用多個字段來排序數據,請使用第二個版本的Find方法來搜索排序鍵值,并將一個對象數組傳遞給它,而且對象數組中各個數據值的順序必須與DataView的 Sort屬性中所指定的字段順序相符。例如:假設要搜索“行銷部”中姓名為“章立民”的員工數據,可以寫代碼:
DataView1.Sort=”部門,姓名”
Dim TargetValues(1) As Object
TargetValues(0)=”行銷部”
TargetValues(1)=”章立民”
Dim rowIndex As Integer=DataView1.Find(TargetValues)
If rowIndex=-1 Then
MessageBox.Show(“找不到您所搜索的部門與姓名”)
Else
MessageBox.Show(DataView1(rowIndex(“姓名”) “的薪資是:” DataView1(rowIndex)(“當前工資”).ToString())
End If
2.3.2 使用DataView的FindRows方法來搜索記錄
FindRows方法提供表3所示的兩個重載版本。
表3 FindRows方法的重載版本

FindRows方法的使用與 Find方法基本一樣,唯一的差異是:FindRows方法的返回值不是一個整數,而是其字段符合指定排序索引鍵值的DataRowView對象數組。如果沒有任何記錄包含指定的排序索引鍵值,則FindRows方法將返回空的DataRowView數組。
2.4 數據修改功能
使用DataView控件可以對綁定的數據源表中的記錄進行新建、修改和刪除。但是,如果用DataView來新建、修改和刪除源表中的記錄,必須將DataView的屬性AllowNew、AllowEdit和AllowDelete屬性設為True(這三個屬性默認值都是True)。
2.4.1 使用DataView新建記錄
將DataView的AllowNew屬性設定為True,便可以使用DataView的AddNew方法來建立新的DataRowView。
注意:
①要等到DataRowView的EndEdit方法被調用時,新記錄才會確實被添加到源表中。如果調用DataRowView的CancelEdit方法,則新記錄將會被舍棄。
②一次只能編輯一個DataRowView。如果當一個未決的記錄存在時,調用了DataRowView的AddNew或BeginEdit方法,則未決的記錄便會隱含調用EndEdit方法。EndEdit方法被調用后,變更就會套用到源表,不過稍后可以調用DataSet、DataTable或DataRow對象的AcceptChanges或RejectChanges方法來提交或拒絕變更。如果AllowNew屬性的設定值為False,則當調用DataRowView的AddNew方法時將會拋出異常。
以下的程序代碼示范如何使用DataView來新建記錄到源表:(設custDS為數據集名,綁定有數據表“章立民工作室”。)
Dim StudioTable As DataTable=custDS.Tables(“章立民工作室”)
Dim StudioView As DataView=StudioTable.DefaultView
StudioView.Sort=”姓名”
StudioView.AllowDelete=False
Dim newDRV As DataRowView=StudioView.AddNew()
newDRV(“身份證號碼”)=”M000111222”
newDRV(“姓名”)=”周時恕”
newDRV.EndEdit ()
2.4.2 使用DataView修改記錄
將DataView的AllowEdit屬性設定為True,則可以通過DataRowView來修改DataRow的內容。可以調用DataRowView.EndEdit方法來確認源記錄的變更,或是調用DataRowView.CancelEdit方法來拒絕變更。
注意:
①一次只能編輯一個記錄。如果當一個未決的記錄存在時,調用了DataRowView的AddNew或BeginEdit方法,則未決的記錄便會隱含調用EndEdit方法。EndEdit方法被調用后,建議的變更就會套用到源DataRow的Current記錄版本,不過稍后可以調用DataSet、DataTable或DataRow對象的AcceptChanges或RejectChanges方法來提交或拒絕變更。如果AllowEdit屬性的設定值為False,則當調用DataRowView的AddEdit方法時將會拋出異常。
②當一個現有的DataRowView正被編輯時,源表的事件仍會與建議的變更一起被引發。如果調用源DataRow的EndEdit或CancelEdit,則不管DataRowView上是否有調用EndEdit或CancelEdit,未決的變更仍會被套用或取消。
2.4.3 使用DataView刪除記錄
將DataView的AllowDelete屬性設定為True,則可以通過DataView或DataRowView對象的Delete方法,從DataView中刪除記錄。稍后可以調用AcceptChanges方法來提交刪除,或是調用RejectChanges方法來拒絕刪除。DataView的Delete方法會刪除指定索引處的記錄,其語法如下所示:
Delete (Byval index As Integer)
如果AllowDelete屬性的設定為False,則當調用DataView或DataRowView的Delete方法時將會拋出異常。
3 結束語
上述技巧在.NET的數據綁定中往往進行綜合運用,大大增強了.NET的數據處理功能,從而增強軟件的數據處理能力。正確靈活地運用DataView的這些技巧,將為應用軟件的開發有很大的幫助。
參考文獻:
[1]何明國,等.Visual Basic.NET程序設計——ADO.NET詳解.中國水利水電出版社,2004.6.
[2]章立民.ADO.NET+VB.NET數據庫應用開發指南.中國鐵道出版社,2004,9.
[3]楊浩(譯),C#數據庫入經典.清華大學出版社,2006.4.