摘要: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