1、創建DataView
創建DataView的方法有兩種,可以使用DataView構造函數,也可以創建對DataTable的DefaultView屬性
的引用。DataView構造函數可以爲空,也可以通過單個參數的形式採用DataTable或者同時採用DataTable
與篩選條件、排序條件和行狀態篩選器。
在創建DataView時或者在修改任何Sort、RowFilter或RowStateFilter屬性時,都會生成DataView的索引,
所以當創建DataView時,通過以構造函數參數的形式提供任何初始排序順序或篩選條件,將實現最佳性能。
//一下代碼使用DataView構造函數創建DataView。RowFilter、Sort和DataViewRowState將與DataTable一起提供
DataView custDV = new DataView(custDS.Tables["Customers"], "Country = 'USA'",
"ContactName", DataViewRowState.CurrentRows);
//以下代碼使用該表的DefaultView屬性獲取對DataTable的默認DataView的引用。
DataView custDV = custDS.Tables["Customers"].DefaultView;
2、使用DataView對數據排序和篩選
DataView提供了幾項用於對DataTable中的數據進行排序和篩選的功能。
使用Sort屬性,可以指定單個或多個列排序順序幷包含升序ASC和降序DESC參數。
可以使用ApplyDefaultSort屬性自動以升序創建基於表的一個或多個主鍵列的排序。只有當Sort屬性爲空
或空字符串時,或者已定義主鍵時,ApplyDefaultSort才適用。
使用RowFilter屬性,可以根據行的列值來指定行的子集。
如果要返回對數據特定查詢的結果(而不是提供數據子集的動態視圖)以實現最佳性能,需要使用DataView的Find
或FindRows方法,而不是設置RowFilter屬性。設置RowFilter會使數據重新生成索引。
//示例代碼:該視圖顯示所有庫存量小於或等於再訂購量的產品,這些產品首先按SupplierID排序,然後再按ProductName排序
DataView prodView = new DataView(prodDS.Tables["Products"], "UnitsInStoc <= ReorderLevel",
"SupplierID, ProductName", DataViewRowState.CurrentRows);
3、使用DataView查看數據
3.1、查看DataView內容
當使用DataView查看時,DataView的RowStateFilter屬性將確定公開基礎DataRow的哪一個行版本。
//以下代碼顯示一個表中所有當前值和初始值
DataView catView = new DataView(catDS.Tables["Categories"]);
Console.WriteLine("Current Values");
WriteView(catView);
Console.WriteLine("Original Values");
catView.RowStateFilter = DataViewRowState.ModifiedOriginal;
WriteView(catView);
public static void WriteView(DataView myView)
{
foreach (DataRowView myDRV in myView)
{
for (int i = 0; i < myView.Table.Columns.Count; i++)
{
Console.Write(myDRV[i] + "\t");
}
Console.WriteLine();
}
}
3.2、搜索DataView內容
使用DataView的Find和FindRows方法,可以按照行的排序關鍵字值來對行進行搜索。
Find方法返回一個整數,該整數表示匹配搜索條件的DataRowView的索引。如果多個行匹配搜索條件,
則只返回第一個匹配DataRowView的索引。如果未找到將返回-1。
如果返回匹配多個行的搜索結果,可以使用FindRows方法。FindRows的工作方式與Find方法類似,不同
的只是FindRows返回引用DataView中所有匹配行的DataRowView數組。如果未找到匹配項,DataRowView
數組爲空。
如果使用Find或FindRows方法,必須通過將ApplyDefaultSort設置爲true或通過使用Sort屬性來指定排序順序,
如果未指定排序順序,則將引發異常。
Find和FindRows方法將一個值數組用作輸入,該數組的長度與排序順序包含的列數組匹配。在對單個列進行排序
的情況下,可以傳遞單個值。對於包含多個列的排序順序,可傳遞一個對象數組。
//當對多個列進行排序時,對象數組中的值必須匹配在DataView的Sort屬性中指定的列的順序。
//以下代碼對具有單個列排序順序的DataView調用Find方法。
DataView custView = new DataView(custDS.Tables["Customers"], "", "CompanyName",
DataViewRowState.CurrentRows);
int rowIndex = custView.Find("The Cracker Box");
if (rowIndex == -1)
{
Console.WriteLine("沒有匹配的結果");
}
else
{
Console.WriteLine("{0}, {1}", custView[rowIndex]["CustomerID"].ToString(),
custView[rowIndex]["CompanyName"].ToString());
}
//以下代碼對多個列排序順序的DataView調用Find方法,如果Sort屬性指定多個列,則必須按
//Sort屬性指定的順序爲每個列傳遞包含搜索值得對象數組
DataView custView = new DataView(custDS.Tables["Customers"], "", "CompanyName,
ContactName", DataViewRowState.CurrentRows);
DataRowView[] foundRows = custView.FindRows(new object[]{"The Cracker Box", "Liu Wong"});
if (foundRows.Length == 0)
{
Console.WriteLine("沒有匹配的結果");
}
else
{
foreach (DataRowView myDRV in foundRows)
{
Console.WriteLine("{0}, {1}", myDRV["CompanyName"].ToString(),
myDRV["CompanyName"].ToString());
}
}
3.3、使用DataView進行關係導航
如果DataSet中的表之間存在關係,則可以使用DataRowView的CreateChildView方法爲父表中的行創建一個DataView,
該DataView包含來自相關子表的行。
//例如,以下代碼按CategoryName和ProductName的字母順序來排序Categories及其相關Products。
DataTable catTable = catDS.Tables["Categories"];
DataTable prodTable = catDS.Tables["Products"];
//創建Categories表和Products表間的關係
DataRelation catProdRel = catDS.Relations.Add("CatProdRel", catTable.Columns["CategoryID"],
prodTable.Columns["CategoryID"]);
//創建Categories表和Products表的DataView
DataView catView = new DataView(catTable, "", "CategoryName", DataViewRowState.CurrentRows);
DataView prodView;
//遍歷Categories表
foreach (DataRowView catDRV in catView)
{
Console.WriteLine(catDRV["CategoryName"]);
//創建產品記錄的子視圖
prodView = catDRV.CreateChildView(catProdRel);
prodView.Sort = "ProductName";
foreach (DataRowView prodDRV in prodView)
{
Console.WriteLine("\t" + prodDRV["ProductName"]);
}
}
4、使用DataView修改數據
默認情況下,DataView是數據的只讀視圖,但是可以使用DataView來添加、刪除、或修改基礎表中的數據行,
方法是設置DataView的3個Boolean屬性之一。這些屬性爲AllowNew、AllowEdit、AllowDelete。
//示例代碼
DataTable custTable = custDS.Tables["Customers"];
DataView custView = custTable.DefaultView;
custView.Sort = "CompanyName";
custView.AllowDelete = false;
DataRowView newDRV = custView.AddNew();
newDRV["CustomerID"] = "ABCDE";
newDRV["CompanyName"] = "ABC Products";
newDRV.EndEdit();
5、使用DataView事件
可以使用DataView的ListChanged事件來確定視圖是否已經由於一下原因而被更新:添加、刪除或修改基礎表中的行;
ListChanged事件還將通知所查看的行列表是否已經由於應用新的排序順序或篩選器而發生重大更改。
//示例代碼:如何添加ListChanged事件處理程序
custView.ListChanged += new System.ComponentModel.ListChangedEventHander(OnListChanged);
//ListChanged事件定義
protected static void OnListChanged(object sender, System.ComponentModel.ListChangedEventArgs args)
{
Console.WriteLine("ListChanged:");
Console.WriteLine("\t Type = " +args.ListChangedType);//改變的類型
Console.WriteLine("\t OldIndex = " +args.OldIndex);//舊地索引
Console.WriteLine("\t NewIndex = " +args.NewIndex);//新的索引
}
6、使用DataViewManager設置默認表視圖
DataViewManager用來管理DataSet中所有表的視圖設置。DataViewManager適合應用於有一個控件要綁定到多個表的情況。
DataViewManager包含DataViewSetting對象的集合,這些對象用於設置DataSet中各個表的視圖設置。對於DataSet中的
每個表,DataViewSettingCollection都包含一個DataViewSetting對象,可以使用所引用表的DataViewSeting來設置該表
的默認ApplyDefaultSort、Sort、RowFilter和RowStateFilter屬性;可以按名稱或序號引用或通過向特定表對象傳遞引用該特定
表的DataViewSetting;可以使用DataViewSetting屬性來訪問DataViewManager中DataViewSetting對象的集合。
//以下代碼示例使用SQL Server的Noerthwind數據庫Customers表、Orders表和Order Details表來填充DataSet,並創建表
//之間的關係,使用DataViewManager設置默認DataView設置,並將DataGrid綁定到DataViewManager。該示例將DataSet中
//多有表的默認DataView設置按表的主鍵進行排序(ApplyDefaultSort = true),然後將Customers表的排序順序修改爲按CompanyName排序。
//創建Connection,DataAdapter和DataSet
SqlConnection nwindConn = new SqlConnection("……");
SqlDataAdapter custDA = new SqlDataAdapter("select CustomerID, CompanyName from Customers", nwindConn);
SqlDataAdapter orderDA = new SqlDataAdapter("select OrderID, CustomerID from Orders", nwindConn);
SqlDataAdapter ordDetDA = new SqlDataAdapter("select OrderID, ProductID, Quantity from [Order Details]", nwindConn);
DataSet custDS = new DataSet();
//打開連接
nwindConn.Open();
//帶着架構信息填充數據集
custDA.MissingSchemaAction = MissingSchemaAction.AddWithKey;
ordDetDA.MissingSchemaAction = MissingSchemaAction.AddWithKey;
ordDetDA.MissingSchemaAction = MissingSchemaAction.AddWithKey;
custDA.Fill(custDS, "Customers");
orderDA.Fill(custDA, "Orders");
ordDetDA.Fill(custDS, "OrderDetails");
//關閉連接
nwindConn.Close();
//創建數據集關係
custDS.Relations.Add("CustomerOrders", custDS.Tables["Customers"].Columns["CustomerID"],
custDS.Tables["Orders"].Columns["CustomerID"]);
custDS.Relations.Add("OrderDetails", custDS.Tables["Orders"].Columns["OrderID"],
custDS.Tables["OrderDetails"].Columns["OrderID"]);
//爲DataSet創建DataViewManager
DataViewManager myDVM = new DataViewManager(custDS);
foreach (DataViewSetting myDVS in myDVM.DataViewSettings)
{
myDVS.ApplyDefaultSort = true;
}
myDVM.DataViewSettings["Customers"].Sort = "CompanyName";
//綁定至DataGrid
System.Windows.Forms.DataGrid myGrid = new System.Windows.Forms.DataGrid();
myGrid.SetDataBinding(myDVM, "Custo