charleschen的麦地

——SomeDay I Will Be Back!

导航

使用ADO.NET2.0提升数据交互性能(5)

Posted on 2006-12-30 17:33  charleschen  阅读(1280)  评论(4编辑  收藏

使用ADO.NET2.0提升数据交互性能(5)

六:DataTable和其他方面的性能提升

另一个好消息是DataTable的功能被大大增强了。毕竟我们不是时时需要Dataset

 

1.装载XML数据

    ADO.NET 1.* 时,离线的数据访问模型以 DataSet 对象为主,因此若要将 XML 的数据装载到 DataTable,必须通过 DataSet 来实现。若我们仅操作一个数据表,不需要访问多个数据表,则还需经过 DataSet 类才能赋予 DataTable 数据或将数据输出成 XML

文件,其过程有点繁琐。ADO.NET 2.0 DataTable 类则新增了与 DataSet 相同的

ReadXMLReadXMLSchemaWriteXML 以及WriteXMLSchema 等方法。因此我们可以直接操作 DataTable 实例,而不需先创建 DataSet 类的实例来赋予 DataTable 实例数据,然后只使用 DataTable 实例。

 

2.结果集直接装载DataTable

   可以通过DataTableReader对象生成DataTableDataSet。利用DataTableDataSet2.0版本中新引入的方法Load,可以传递DataTableReader或者任何实现IDataReader接口的类对象。下面的代码就是通过Load方法将dt1的数据传递到新的数据表dt2中:

DataTableReader dtRdr = dt1.CreateDataReader();
DataTable dt2 = new DataTable();
dt2.Load(dtRdr);

在使用Load方法装载多行数据时,可以先调用BeginLoadData方法来避免通知(notifications),索引维护(index maintenance)以及约束检查(constraint checking),然后再通过EndLoadData方法返回数据。

 

3.通过 SqlDataAdapter 类实例将 DataTable 内的记录更新回数据源

现在我们还可以使用 SqlDataAdapter 类实例通过 DataGridView 更新的记录。

Update方法由以下几个重载:

public int Update(DataRow[] dataRows);

public override int Update(DataSet dataSet);

public int Update(DataTable dataTable);

public int Update(DataSet dataSet, string srcTable);

 

4.千呼万唤的Merge方法,终于实现了。

public void Merge(DataTable table);

public void Merge(DataTable table, bool preserveChanges);

public void Merge(DataTable table, bool preserveChanges, MissingSchemaAction missingSchemaAction);

preserveChanges:参数决定当前 DataTable在相同主键记录合并时,是保留数据表内当前更新过的记录(设置为 True),还是以合并来的记录覆盖掉曾经修改过的记录(设置为 False)。

5

轻量级对象和快速遍历

ADO.NET 2.0中的DataTable提供了CreateDataReader方法(在之前的版本名为GetDataReader),该方法将创建一个DataTableReader对象。DataTableReaderDataTable不同,它是一个轻量级的对象,其支持Disconnected,这一点与DataReaderSqlDataReader)不同。这些特点决定遍历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");
adpt.Fill(dtCustomers);
DataTableReader dtRdr = ds.CreateDataReader();
dgvCustomers.DataSource = 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");
adpt.Fill(dtCustomers);

DataSet ds = new DataSet();
ds.Tables.Add(dtCustomers);
adpt.SelectCommand = new SqlCommand("SELECT * FROM Orders", cn);

adpt.Fill(ds, "Orders");


// Create the DataTableReader (it is disconnected)
using(DataTableReader dtRdr = ds.CreateDataReader())
{
do
{
Console.WriteLine("******************************");
while (dtRdr.Read())
{
Console.WriteLine(dtRdr.GetValue(0).ToString());
}
}
while (dtRdr.NextResult());
}
}

DataTableReader
对象中数据表的顺序与DataSet中的数据表顺序一致。如果你需要制定特定的顺序,可以通过重载CreateDataReader方法来实现。

6.其他的更新

Connection Pool操作

 

ADO.NET 1.0 就已经引进了数据库连接 pooling 的新架构,但只有 SqlClient OracleClient

两个数据提供者使用这种架构,OLE DB ODBC 因为沿用以往的程序架构,有自己的 pooling 机制。

.NET pooling 架构提供了较 OLE DBODBC 更细致的控制,例如设置 pool 内最大与最小的连接数目,pool manager

等待可用连接的时间,可程序化地清空 pool(也就是关闭其内的连接)等。你可以通过静态方法(VB.NET 称为 Shared

SqlConnection.ClearPool 清空某个特定的 connection pool,或是以静态方法 SqlConnection.ClearPools

清掉某个 AppDomain 内所有的 Connection Pool

 

新的隔离级别

行隔离级别和SYSTEM.Transaction事务,行隔离级别是2005新的隔离级别,可以大大提升数据交互的并发性。

SYSTEM.Transaction事务可以使用DTC(Distributed Transaction Coordinator,分布式事务协调)完成分布式事务。但是这个东东的速度。。。。。

其实,只要你打开两条以上的连接,尽管这两条连接是访问同一个数据库,都会发生分布式事务,就因为需要 DTCDistributed Transaction

Coordinator)的参与,将会导致速度比原先本地事务慢 10 倍以上