6.10 DataView类
DataView使你能够创建DataTable中所存储的数据的不同视图,从而可以使用不同排序顺序来显示表中的数据,并且可以按行状态或基于筛选器表达式来筛选数据。
与DataTable的Select方法不同的是,DataView提供基础DataTable中的数据的动态视图:内容、排序和成员关系会实时反映其更改。因此,使用DataView不会影响DataTable里的真实数据。例如,假设过滤一个表从而隐藏了某些行,这些行仍然在DataTable中,但它们却不能够通过DataView访问到。
6.10.1 排序数据
要使用DataView排序数据,就得先创建一个DataView对象。通常,创建DataView的方法有两种:
1)使用DataView构造函数。DataView构造函数可以为空,还可以采用DataTable作为单个参数,还可以同时采用DataTable与筛选条件、排序条件和行状态筛选器。如下面的示例代码演示如何使用DataView构造函数来创建一个DataView。其中,RowFilter、Sort列和DataViewRowState将与DataTable一起提供:
DataView dv=new DataView(ds.Tables["Employee"],
"department='软件研发部'",
"employeename",
DataViewRowState.CurrentRows);
2)创建对DataTable的DefaultView属性的引用。虽然可以在同一表上创建多个不同视图的DataView对象,但每个DataTable都有一个默认的DataView和它相关联。其中,默认的DataView可以通过DataView的DefaultView属性来指定,如下面的示例代码所示:
DataView dv=ds.Tables["Employee"].DefaultView;
对于使用DataView排序数据[ASC(升序)和DESC(降序)],可以使用如下三种方法:
1)直接在DataView构造函数里进行排序,如上面的示例所示。
2)使用Sort属性来显式地进行排序,如下面的代码所示:
dv.Sort="employeename";
3)使用ApplyDefaultSort属性自动以升序创建基于表的一个或多个主键列的排序顺序。只有当Sort属性为空引用或空字符串时以及表已定义主键时,ApplyDefaultSort才适用。其中,如果使用默认排序,则为true;否则为false。
6.10.2 过滤数据
除了可以使用DataView对数据进行排序之外,还可以利用逻辑操作符号与一系列条件来过滤数据,从而限制显示的结果。同样,使用DataView过滤数据的方法也有如下两种:
1)直接在DataView构造函数里进行过滤,如上面的示例所示。
2)通过显式地使用RowFilter属性来进行数据过滤,RowFilter属性与SQL语句中的where子句相似。如下面的代码所示:
dv.RowFilter="department='软件研发部'";
除了上面的一些简单的过滤方法之外,还可以通过关系来进行高级过滤。同时,DataView支持一些常用的聚合函数,如avg()、max()、min()、count()等。下面先来创建一个DataRelation,并将该关系添加到DataSet(ds):
DataRelation rel=new DataRelation("EmployeeSalary",
ds.Tables["Employee"].Columns["employeeid"],
ds.Tables["Salary"].Columns["employeeid"]);
ds.Relations.Add(rel);
现在,就可以利用上面的表关系来过滤数据了,如下面的代码所示:
DataView dv=new DataView(ds.Tables["Employee"]);
dv.RowFilter="max(Child(EmployeeSalary).salary)>3900";
还可以使用下面的形式将这些数据输出来,如下面的代码所示:
foreach(DataRowView rowView in dv)
{
for(int i=0;i<dv.Table.Columns.Count;i++)
{
Label1.Text+=rowView[i].ToString();
}
}
6.10.3 计算列
其实,在实际开发中,除了可以在表格处理直接从数据源中获取的数据字段之外,还可以加入自己定义的计算列。在读取或者更新数据时,这些计算列将被忽略,它们只是表示计算现有值的结果的组合。下面的示例演示了如何使用计算列。
作为示例,首先需要创建一个DataSet,如下面的代码所示:
public DataSet GetEmployee()
{
string connectionString=
WebConfigurationManager.ConnectionStrings
["ConnectionString"].ConnectionString;
string employeeSql="select*from Employee";
string salarySql="select*from Salary";
SqlConnection con=new SqlConnection(connectionString);
SqlDataAdapter adapter=new SqlDataAdapter(employeeSql, con);
DataSet ds=new DataSet();
using(con)
{
con.Open();
//将Employee表填充到DataSet
adapter.Fill(ds,"Employee");
//将Salary表填充到DataSet
adapter.SelectCommand.CommandText=salarySql;
adapter.Fill(ds,"Salary");
}
//将Salary与Employee通过employeeid来建立关系
DataRelation rel=new DataRelation("EmployeeSalary",
ds.Tables["Employee"].Columns["employeeid"],
ds.Tables["Salary"].Columns["employeeid"]);
ds.Relations.Add(rel);
return ds;
}
创建好DataSet之后,需要在该DataSet的Employee表中添加一些计算列,以方便显示。创建一个计算列时,只要简单地创建一个新的DataColumn对象,同时指定该DataColumn对象的名称、类型和Expression属性。最后,将创建的DataColumn对象用DataTable的Add()方法添加到Columns集合中就可以了。如下面的代码所示:
protected void Page_Load(object sender, EventArgs e)
{
DataSet ds=GetEmployee();
DataColumn total=new DataColumn("总工资",
typeof(double),"max(Child(EmployeeSalary).total)");
DataColumn salestax=new DataColumn("应交税款",
typeof(double),"max(Child(EmployeeSalary).salestax)");
DataColumn salary=new DataColumn("实际工资",
typeof(double),"max(Child(EmployeeSalary).salary)");
ds.Tables["Employee"].Columns.Add(total);
ds.Tables["Employee"].Columns.Add(salestax);
ds.Tables["Employee"].Columns.Add(salary);
GridView1.DataSource=ds.Tables["Employee"];
GridView1.DataBind();
}
示例运行结果如图6-35所示。
图 6-35 示例运行结果
6.10.4 将DataSet、DataTable和DataView转换成XML
实际开发中,经常面临着将DataSet、DataTable和DataView转换成XML的相关处理。其实,要将DataSet、DataTable和DataView转换成XML,其方法很简单,只需要利用DataTable或者DataSet的WriteXml()方法就可以完成相关处理。WriteXml()方法提供了只将数据或同时将数据和架构从DataTable写入XML文档的方法。
代码清单6-4封装了将DataSet、DataTable和DataView转换成XML的常用方法,读者可以直接调用这些方法来完成相关的处理任务。
代码清单6-4 DataToXml.cs
using System;
using System.Collections.Generic;
using System.Data;
using System.Web;
using System.Text;
using System.Xml;
using System.IO;
namespace_6_4
{
public class DataToXml
{
///<summary>
///将DataTable对象转换成XML字符串
///</summary>
///<param name="dt">DataTable对象</param>
///<returns>XML字符串</returns>
public static string DataTableToXml(DataTable dt)
{
if(dt!=null)
{
MemoryStream ms=null;
XmlTextWriter writer=null;
try
{
ms=new MemoryStream();
//根据ms实例化writer
writer=new XmlTextWriter(ms, Encoding.Unicode);
//获取DataTable中的数据
dt.WriteXml(writer);
int count=((it)ms.Length;
byte[]temp=new byte[count];
ms.Seek(0,SeekOrigin.Begin);
ms.Read(temp,0,count);
//返回Unicode编码的文本
UnicodeEncoding ucode=new UnicodeEncoding();
string returnValue=
ucode.GetString(temp).Trim();
return returnValue;
}
catch(System.Exception ex)
{
throw ex;
}
finally
{
//释放资源
if(writer!=null)
{
writer.Close();
ms.Close();
ms.Dispose();
}
}
}
else
{
return"DataTable为null";
}
}
///<summary>
///将DataSet对象转换成XML字符串
///</summary>
///<param name="ds">DataSet对象</param>
///<returns>XML字符串</returns>
public static string DataSetToXml(DataSet ds)
{
if(ds!=null)
{
MemoryStream ms=null;
XmlTextWriter writer=null;
try
{
ms=new MemoryStream();
//根据ms实例化writer
writer=new XmlTextWriter(ms, Encoding.Unicode);
//获取DataSet中的数据
ds.WriteXml(writer);
int count=((it)ms.Length;
byte[]temp=new byte[count];
ms.Seek(0,SeekOrigin.Begin);
ms.Read(temp,0,count);
//返回Unicode编码的文本
UnicodeEncoding ucode=new UnicodeEncoding();
string returnValue=
ucode.GetString(temp).Trim();
return returnValue;
}
catch(System.Exception ex)
{
throw ex;
}
finally
{
//释放资源
if(writer!=null)
{
writer.Close();
ms.Close();
ms.Dispose();
}
}
}
else
{
return"DataSet为null";
}
}
///<summary>
///将DataSet对象中指定的Table转换成XML字符串
///</summary>
///<param name="ds">DataSet对象</param>
///<param name="tableIndex">DataSet对象中的Table索引</param>
///<returns>XML字符串</returns>
public static string DataSetToXml(DataSet ds,
int tableIndex)
{
if(tableIndex!=-1)
{
return DataTableToXml(ds.Tables[tableIndex]);
}
else
{
return DataSetToXml(ds);
}
}
///<summary>
///将DataView对象转换成XML字符串
///</summary>
///<param name="dv">DataView对象</param>
///<returns>XML字符串</returns>
public static string DataViewToXml(DataView dv)
{
return DataTableToXml(dv.Table);
}
///<summary>
///将DataTable对象数据保存为XML文件
///</summary>
///<param name="dt">DataTable</param>
///<param name="xmlPath">XML文件路径</param>
///<returns>bool值</returns>
public static bool DataTableToXml(DataTable dt,
string xmlPath)
{
if(((d!=null)&&(!string.IsNullOrEmpty(xmlPath)))
{
string path=
HttpContext.Current.Server.MapPath(xmlPath);
MemoryStream ms=null;
XmlTextWriter writer=null;
try
{
ms=new MemoryStream();
//根据ms实例化writer
writer=new XmlTextWriter(ms, Encoding.Unicode);
//获取dt中的数据
dt.WriteXml(writer);
int count=((it)ms.Length;
byte[]temp=new byte[count];
ms.Seek(0,SeekOrigin.Begin);
ms.Read(temp,0,count);
//返回Unicode编码的文本
UnicodeEncoding ucode=new UnicodeEncoding();
//写文件
StreamWriter sw=new StreamWriter(path);
sw.WriteLine("<?xml version=\"1.0\"
encoding=\"utf-8\"?>");
sw.WriteLine(ucode.GetString(temp).Trim());
sw.Close();
return true;
}
catch(System.Exception ex)
{
throw ex;
}
finally
{
//释放资源
if(writer!=null)
{
writer.Close();
ms.Close();
ms.Dispose();
}
}
}
else
{
return false;
}
}
///<summary>
///将DataSet对象数据保存为XML文件
///</summary>
///<param name="ds">DataSet</param>
///<param name="xmlPath">XML文件路径</param>
///<returns>bool值</returns>
public static bool DataSetToXml(DataSet ds, string xmlPath)
{
if(((d!=null)&&(!string.IsNullOrEmpty(xmlPath)))
{
string path=
HttpContext.Current.Server.MapPath(xmlPath);
MemoryStream ms=null;
XmlTextWriter writer=null;
try
{
ms=new MemoryStream();
//根据ms实例化writer
writer=new XmlTextWriter(ms, Encoding.Unicode);
//获取ds中的数据
ds.WriteXml(writer);
int count=((it)ms.Length;
byte[]temp=new byte[count];
ms.Seek(0,SeekOrigin.Begin);
ms.Read(temp,0,count);
//返回Unicode编码的文本
UnicodeEncoding ucode=new UnicodeEncoding();
//写文件
StreamWriter sw=new StreamWriter(path);
sw.WriteLine("<?xml version=\"1.0\"
encoding=\"utf-8\"?>");
sw.WriteLine(ucode.GetString(temp).Trim());
sw.Close();
return true;
}
catch(System.Exception ex)
{
throw ex;
}
finally
{
//释放资源
if(writer!=null)
{
writer.Close();
ms.Close();
ms.Dispose();
}
}
}
else
{
return false;
}
}
///<summary>
///将DataSet对象中指定的Table转换成XML文件
///</summary>
///<param name="ds">DataSet对象</param>
///<param name="tableIndex">DataSet对象中的Table索引</param>
///<param name="xmlPath">xml文件路径</param>
///<returns>bool值</returns>
public static bool DataSetToXml(DataSet ds,
int tableIndex, string xmlPath)
{
if(tableIndex!=-1)
{
return DataTableToXml(ds.Tables[tableIndex],xmlPath);
}
else
{
return DataSetToXml(ds, xmlPath);
}
}
///<summary>
///将DataView对象转换成XML文件
///</summary>
///<param name="dv">DataView对象</param>
///<param name="xmlPath">xml文件路径</param>
///<returns>bool值</returns>
public static bool DataViewToXml(DataView dv,
string xmlPath)
{
return DataTableToXml(dv.Table, xmlPath);
}
}
}
6.10.5 将XML转换成DataSet、DataTable
与WriteXml()使用方法一样,你也可以使用ReadXml()方法将XML架构和数据读入DataSet。代码清单6-5封装了将XML转换成DataSet、DataTable的常用方法,读者可以直接调用这些方法来完成相关的处理任务。
代码清单6-5 XmlToData.cs
using System;
using System.Collections.Generic;
using System.Data;
using System.Web;
using System.Text;
using System.Xml;
using System.IO;
namespace_6_4
{
public class XmlToData
{
///<summary>
///将Xml内容字符串转换成DataSet对象
///</summary>
///<param name="xml">Xml内容字符串</param>
///<returns>DataSet对象</returns>
public static DataSet XmlToDataSet(string xml)
{
if(!string.IsNullOrEmpty(xml))
{
StringReader strReader=null;
XmlTextReader reader=null;
try
{
DataSet ds=new DataSet();
//读取字符串中的信息
strReader=new StringReader(xml);
//获取strReader中的数据
reader=new XmlTextReader(strReader);
//ds获取reader中的数据
ds.ReadXml(reader);
return ds;
}
catch(Exception e)
{
throw e;
}
finally
{
//释放资源
if(reader!=null)
{
reader.Close();
strReader.Close();
strReader.Dispose();
}
}
}
else
{
return null;
}
}
///<summary>
///将Xml字符串转换成DataTable对象
///</summary>
///<param name="xml">Xml字符串</param>
///<param name="tableIndex">Table表索引</param>
///<returns>DataTable对象</returns>
public static DataTable XmlToDatatTable(string xml,
int tableIndex)
{
return XmlToDataSet(xml).Tables[tableIndex];
}
///<summary>
///将Xml字符串转换成DataTable对象
///</summary>
///<param name="xml">Xml字符串</param>
///<returns>DataTable对象</returns>
public static DataTable XmlToDatatTable(string xml)
{
return XmlToDataSet(xml).Tables[0];
}
///<summary>
///读取Xml文件信息,并转换成DataSet对象
///</summary>
///<param name="xmlPath">Xml文件地址</param>
///<returns>DataSet对象</returns>
public static DataSet XmlFileToDataSet(string xmlPath)
{
if(!string.IsNullOrEmpty(xmlPath))
{
string path=
HttpContext.Current.Server.MapPath(xmlPath);
StringReader strReader=null;
XmlTextReader reader=null;
try
{
XmlDocument xmldoc=new XmlDocument();
//根据地址加载Xml文件
xmldoc.Load(path);
DataSet ds=new DataSet();
//读取文件中的字符流
strReader=new StringReader(xmldoc.InnerXml);
//获取strReader中的数据
reader=new XmlTextReader(strReader);
//ds获取reader中的数据
ds.ReadXml(reader);
return ds;
}
catch(Exception e)
{
throw e;
}
finally
{
//释放资源
if(reader!=null)
{
reader.Close();
strReader.Close();
strReader.Dispose();
}
}
}
else
{
return null;
}
}
///<summary>
///读取Xml文件信息,并转换成DataTable对象
///</summary>
///<param name="xmlPath">xml文件路径</param>
///<param name="tableIndex">Table索引</param>
///<returns>DataTable对象</returns>
public static DataTable XmlToDataTable(string xmlPath,
int tableIndex)
{
return XmlFileToDataSet(xmlPath).Tables[tableIndex];
}
///<summary>
///读取Xml文件信息,并转换成DataTable对象
///</summary>
///<param name="xmlPath">xml文件路径</param>
///<returns>DataTable对象</returns>
public static DataTable XmlToDataTable(string xmlPath)
{
return XmlFileToDataSet(xmlPath).Tables[0];
}
}
}