相关文章推荐
睡不着的豌豆  ·  make, makefile, ...·  3 年前    · 

摘要:ADO.NET 2.0 - 如何建立一個 DataView

借助於 DataView ,我們便能夠替儲存於 DataTable 中的資料建立不同的檢視。比方說,透過 DataView ,您可以使用不同的排序順序檢視 DataTable 中的資料,亦或是根據資料列狀態或篩選運算式來篩選 DataTable 中的資料。重要的是,當我們需要替 DataTable 中的資料建立不同的檢視而且需要將這些資料繫結至表單上的控制項時,更需要使用 DataView 來完成之。

DataView 提供的是一種 動態 的資料檢視,也就是說,其內容、排序順序、與成員會反應出來源 DataTable 中的任何變更。顯然 DataView 與 DataTable.Select 方法有很大的不同, Select 方法會根據特定的篩選運算式或排序順序從資料表中傳回一個 DataRow 物件陣列,而且其成員與排序順序是靜態不變的。正由於 DataView 的動態反應特性,因此非常適合用於資料繫結應用程式。

DataView 提供您單一資料集合的動態檢視,您可以對資料集合套用不同的排序順序和篩選條件,此點與 SQL Server 資料庫所提供的檢視表( View )有點類似。然而, DataView 與資料庫檢視表仍然有相當大的差異,因為 DataView 無法當成資料表來使用,也無法提供連結資料表的檢視。此外,您不僅不能排除來源資料表中的欄位,也不能額外加入來源資料表中不存在的欄位(例如:運算式欄位)。

您可以採用兩種方式來建立一個 DataView 。第一種方式是使用 DataView 建構函式,第二種方式則是建立 DataTable 之 DefaultView 屬性的一個參考。 本文將詳細探討如何使用這兩種方式來建立 DataView 。

使用 DataView 建構函式

DataView 建構函式共提供下表所示的三個多載版本。

DataView 建構函式的多載版本

DataView()

DataView(ByVal table As DataTable )

DataView(ByVal table As DataTable , _
ByVal RowFilter As String , _
ByVal Sort As String , _
ByVal RowState As DataViewRowState )

DataView 建構函式的第一個版本表示不使用任何參數來初始化 DataView 類別的新執行個體。請注意,如果您採用此版本來建立 DataView ,必須在建立 DataView 物件後先設定 Table 屬性以便決定其來源 DataTable ,然後才能繼續設定其他屬性( RowFilter 、 Sort … 等等)。

以下的程式碼示範如何使用第一個版本的 DataView 建構函式來建立 DataView 物件,以便篩選和排序資料集內之 「章立民工作室」 資料表的資料列,並將 DataGridView 控制項繫結至此 DataView 。我們發現, DataGrid 控制項只會顯示出女性,並且資料會依姓名的筆畫順序由多至少排列。以下是本範例的程式碼:

SqlDataAdapter1.Fill(Ds 章立民工作室 , " 章立民工作室 " )
'
建立 DataView 物件
Dim dv As DataView = New DataView

'
由於採用沒有任何參數的 DataView 建構函式來建立 DataView 物件,
'
因此必須先設定 Table 屬性以便決定其來源 DataTable
dv.Table = Ds 章立民工作室 . 章立民工作室

'
設定排序順序以便依姓名的筆畫順序由多至少排列
dv.Sort = " 姓名 DESC"

' 設定篩選條件以便只顯示出女性
dv.RowFilter = " 性別 = ' 女 '"

' 將 DataGridView 控制項繫結至 DataView
DataGridView1.DataSource = dv

DataView 建構函式的第二個版本表示使用指定的 DataTable 來初始化 DataView 類別的新執行個體。

以下的程式碼它示範如何使用第二個版本的 DataView 建構函式來建立 DataView 物件,以便篩選和排序資料集內之 「章立民工作室」 資料表的資料列,並將 DataGridView 控制項繫結至此 DataView 。我們發現, DataGridView 控制項只會顯示出 「資訊部」 的員工資料,並且資料會依照目前薪資由高至低排列:

SqlDataAdapter1.Fill(Ds 章立民工作室 , " 章立民工作室 " )

'
建立 DataView 物件
Dim dv As DataView = New DataView(Ds 章立民工作室 . 章立民工作室 )

'
設定排序順序以便依目前薪資由高至低排列
dv.Sort = " 目前薪資 DESC"

' 設定篩選條件以便只顯示出「資訊部」的員工資料
dv.RowFilter = " 部門 = ' 資訊部 '"

' 將 DataGridView 控制項繫結至 DataView
Me .DataGridView1.DataSource = dv

DataView 建構函式的第三個版本表示使用指定的 DataTable 、 RowFilter 、 Sort 和 DataViewRowState ,來初始化 DataView 類別的新執行個體。

以下的程式碼它示範如何使用第三個版本的 DataView 建構函式來建立 DataView 物件,以便篩選和排序資料集內之 「章立民工作室」 資料表的資料列,並將 DataGridView 控制項繫結至此 DataView 。我們發現, DataGridView 控制項只會顯示出目前薪資大於 49000 元的員工資料,並且資料會依照目前薪資由高至低排列:

SqlDataAdapter1.Fill(Ds 章立民工作室 , " 章立民工作室 " )

'
建立 DataView 物件
Dim dv As DataView = New DataView( _
Ds
章立民工作室 . 章立民工作室 , _
"
目前薪資 > 49000" , _
"
目前薪資 DESC" , _
DataViewRowState.CurrentRows)
'
將 DataGridView 控制項繫結至 DataView

Me .DataGridView1.DataSource = dv

在此要特別提醒大家,當 DataView 被建立時,以及當 Sort 、 RowFilter 或 RowStateFilter 屬性有任何一個被修改時,都會重新建立 DataView 的索引。此意味著,如果您希望享有最佳的效能,應該在建立 DataView 時,直接於建構函式中指定排序順序或篩選條件。如果您於建立 DataView 時並未直接於建構函式中指定排序順序或篩選條件,而是於建立 DataView 物件之後再設定其 Sort 、 RowFilter 或 RowStateFilter 屬性,將會導致 DataView 的索引被重新建立,而使得索引至少被建立兩次。

使用 DataTable 的 DefaultView 屬性

DataTable 的 DefaultView 屬性會傳回一個以此 DataTable 作為來源資料表的 DataView 物件,您便讓您去排序、篩選、與搜尋 DataTable 中的資料列。如果您所建立的 DataView 要顯示出 DataTable 中的所有資料列並依照自然順序來排列,則使用 DataTable 的 DefaultView 屬性來建立 DataView 將是非常直接且便利的方式。

以執行畫面如圖表 1 所示的程式而言,它使用 DataTable 的 DefaultView 屬性來建立 DataView ,以便一開始能夠於 DataGrid 控制項中顯示出來源資料表的所有資料列,並讓使用者在執行階段透過 DataView 來動態篩選資料。茲將程式碼列示如下:

' DataView 物件的類別層級宣告
Private dv As DataView

Private Sub DemoForm5_Load( ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase .Load
FillComboBoxDepartment()

SqlDataAdapter1.Fill(Ds
章立民工作室 , " 章立民工作室 " )

'
建立 DataView
dv = Ds 章立民工作室 . 章立民工作室 .DefaultView

'
顯示 DataView 中的資料列數目
txtRowCount.Text = dv.Count.ToString

'
將 DataGridView 控制項繫結至 DataView
Me .DataGridView1.DataSource = dv
End Sub

Private
Sub FillComboBoxDepartment()
'
建立資料命令物件 ( 亦即 SqlCommand 物件 )
Dim foxCMD As New SqlCommand
foxCMD.Connection = SqlConnection1
foxCMD.CommandText = "SELECT DISTINCT
部門 FROM dbo. 章立民工作室 "

' 開啟連接
SqlConnection1.Open()

Using myReader As SqlDataReader = foxCMD.ExecuteReader()
If myReader.HasRows Then
While myReader.Read()
ComboBoxDepartment.Items.Add(myReader.GetSqlString(0))
End While
End If
End Using
ComboBoxDepartment.SelectedIndex = 0
End Sub

Private
Sub btnFilter_Click( ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnFilter.Click
dv.RowFilter = "
部門 = '" & _
ComboBoxDepartment.SelectedItem.ToString() & "'"
' 顯示 DataView 中的資料列數目
txtRowCount.Text = dv.Count.ToString
End Sub

圖表 1