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