John Papa的一篇文章《DataSet and DataTable in ADONET 》详细介绍了ADONet 的一些新功能和特性对于利用ADONET开发的程序员来说是值得关注的现介绍如下
一功能增强的DataTable
在ADONETx中DataSet完全掩盖了DataTable的光芒并非DataTable自身功能不够强大实则是比较DataSet而言很多功能在x版本中受到了限制例如Merge功能在ADONETx版本中如果要合并两个表只有是通过DataSet的Merge方法才能完成代码如下
string sqlAllCustomers = SELECT * FROM Customers
string cnStr = @Data Source=Initial Catalog=northwindIntegrated Security=True
using (SqlConnection cn = new SqlConnection(cnStr))
{
cnOpen();
SqlCommand cmd = new SqlCommand(sqlAllCustomers cn);
SqlDataAdapter adpt = new SqlDataAdapter(cmd);
DataTable dtCust = new DataTable(Customers);
adptFill(dtCust);
dtCustPrimaryKey = new DataColumn[]{dtCustColumns[CustomerID]};
DataTable dtCust = dtCustClone();
DataRow row = dtCustNewRow();
row[CustomerID] = ALFKI;
row[CompanyName] = Some Company;
dtCustRowsAdd(row);
DataRow row = dtCustNewRow();
row[CustomerID] = FOO;
row[CompanyName] = Some Other Company;
dtCustRowsAdd(row);
DataSet ds = new DataSet(MySillyDataSet);
dsTablesAdd(dtCust);
dsMerge(dtCust);
dgTestDataSource = dtCust;
}
在ADONET 中对DataTable作了改进同样提供了Merge方法因此如上的代码中如果要合并表dtCust和dtCust就不必再引入DataSet对象了
dtCustMerge(dtCust)
此外ADONETx版本中DataTable也无法完成Xml文件和数据表之间的转换这个问题在版本中也得到了改进DataTable也具备了和DataSet对象同样的操作xml文件的能力包括方法ReadXmlWriteXml等
DataSet和DataTable在版本中还提供了一个新的属性RemotingFormat在对DataTable和DataSet对象进行序列化时该属性标示序列化的格式是二进制还是xml
二轻量级对象和快速遍历
ADONET 中的DataTable提供了CreateDataReader方法(在之前的版本名为GetDataReader)该方法将创建一个DataTableReader对象DataTableReader与DataTable不同它是一个轻量级的对象其支持Disconnected这一点与DataReader(SqlDataReader)不同这些特点决定遍历DataTableReader对象将更加快速占用的数据资源更少(Disconnected)下面的代码创建了一个DataTableReader对象并将其绑定到DataGridView控件上
using (SqlConnection cn = new SqlConnection(cnStr))
{
SqlCommand cmd = new SqlCommand(sqlAllCustomers cn);
SqlDataAdapter adpt = new SqlDataAdapter(cmd);
DataTable dtCustomers = new DataTable(Customers);
adptFill(dtCustomers);
DataTableReader dtRdr = dsCreateDataReader();
dgvCustomersDataSource = dtRdr;
}
和DataReader一样DataTableReader对象只能向前遍历可以通过Read方法定位到对象的第一行如果DataTableReader如果是被一个包含有多个数据表的DataSet对象创建DataTableReader也会包含多个结果集通过调用NextResult方法访问结果集序列
using (SqlConnection cn = new SqlConnection(cnStr))
{
// Create the Command and Adapter
SqlCommand cmd = new SqlCommand(sqlAllCustomers cn);
SqlDataAdapter adpt = new SqlDataAdapter(cmd);
// Create a DataTable and fill it
DataTable dtCustomers = new DataTable(Customers);
adptFill(dtCustomers);
DataSet ds = new DataSet();
dsTablesAdd(dtCustomers);
adptSelectCommand = new SqlCommand(SELECT * FROM Orders cn);
adptFill(ds Orders);
// Create the DataTableReader (it is disconnected)
using(DataTableReader dtRdr = dsCreateDataReader())
{
do
{
ConsoleWriteLine(******************************);
while (dtRdrRead())
{
ConsoleWriteLine(dtRdrGetValue()ToString());
}
}
while (dtRdrNextResult());
}
}
DataTableReader对象中数据表的顺序与DataSet中的数据表顺序一致如果你需要制定特定的顺序可以通过重载CreateDataReader方法来实现
三装载数据
可以通过DataTableReader对象生成DataTable和DataSet利用DataTable和DataSet在版本中新引入的方法Load可以传递DataTableReader或者任何实现IDataReader接口的类对象下面的代码就是通过Load方法将dt的数据传递到新的数据表dt中
DataTableReader dtRdr = dtCreateDataReader()
DataTable dt = new DataTable()
dtLoad(dtRdr)
在使用Load方法装载多行数据时可以先调用BeginLoadData方法来避免通知(notifications)索引维护(index maintenance)以及约束检查(constraint checking)然后再通过EndLoadData方法返回数据
四性能改进
这恐怕是ADONET 最激动人心的改进在x版本中随着数据的增大在使用DataTable和DataSet对象时性能是不能令人满意的ADONET 对索引引擎作了很大的改进使得的数据访问能力获得极大的提高以下面的测试代码为例
DataTable dt = new DataTable(foo);
DataColumn pkCol = new DataColumn(ID TypeGetType(SystemInt));
pkColAutoIncrement = true;
pkColAutoIncrementSeed = ;
pkColAutoIncrementStep = ;
dtColumnsAdd(pkCol);
dtPrimaryKey = new DataColumn[] { pkCol };
dtColumnsAdd(SomeNumber TypeGetType(SystemInt));
dtColumns[SomeNumber]Unique = true;
int limit = ;
int someNumber = limit;
DateTime startTime = DateTimeNow;
for (int i = ; i <= limit; i++)
{
DataRow row = dtNewRow();
row[SomeNumber] = someNumber—;
dtRowsAdd(row);
}
TimeSpan elapsedTime = DateTimeNow startTime
MessageBoxShow(dtRowsCountToString() + rows loaded in + elapsedTimeTotalSeconds + seconds)
分别在Visual StudioNET 和Visual Studio 环境下运行结果比较如下
Iterations
ADONET
ADONET