ADO.NET 的最佳实践技巧(6)

对数据库的命令中,当把空值作为参数值发送时,不能使用 null(Visual Basic庐 .NET 中为 Nothing)。而需要使用 DBNull.Value。例如:

'Visual Basic Dim param As SqlParameter = New SqlParameter("@Name", SqlDbType.NVarChar, 20) param.Value = DBNull.Value //C# SqlParameter param = new SqlParameter("@Name", SqlDbType.NVarChar, 20); param.Value = DBNull.Value;

执行事务

ADO.NET 的事务模型已经更改。在 ADO 中,当调用 StartTransaction 时,调用之后的任何更新操作都被视为是事务的一部分。但是,在 ADO.NET 中,当调用 Connection.BeginTransaction 时,会返回一个 Transaction 对象,需要把它与 CommandTransaction 属性联系起来。这种设计可以在一个单一连接上执行多个根事务。如果未将 Command.Transaction 属性设置为一个针对相关的 Connection 而启动的 Transaction,那么 Command 就会失败并引发异常。

即将发布的 .NET 框架将使您可以在现有的分布式事务中手动登记。这对于对象池方案来说很理想;在该方案中,一个池对象打开一次连接,但是在多个独立的事务中都涉及到该对象。.NET 框架 1.0 发行版中这一功能并不可用。

有关事务的更多信息,请参阅 Performing Transactions 以及 .NET Data Access Architecture Guide。

使用连接

高性能应用程序与使用中的数据源保持最短时间的连接,并且利用性能增强技术,例如连接池。下面的主题提供一些技巧,有助于在使用 ADO.NET 连接到数据源时获得更好的性能。

连接池

用于 ODBC 的 SQL Server、OLE DB 和 .NET 框架数据提供程序隐式缓冲连接。通过在连接字符串中指定不同的属性值,可以控制连接池的行为。有关如何控制连接池的行为的详细信息,请参阅 Connection Pooling for the SQL Server .NET Data Provider 和 Connection Pooling for the OLE DB .NET Data Provider。

用 DataAdapter 优化连接

DataAdapterFillUpdate 方法在连接关闭的情况下自动打开为相关命令属性指定的连接。如果 FillUpdate 方法打开了连接,FillUpdate 将在操作完成的时候关闭它。为了获得最佳性能,仅在需要时将与数据库的连接保持为打开。同时,减少打开和关闭多操作连接的次数

如果只执行单个的 FillUpdate 方法调用,建议允许 FillUpdate 方法隐式打开和关闭连接。如果对 Fill 和/或 Update 调用有很多,建议显式打开连接,调用 Fill 和/或 Update,然后显式关闭连接。

另外,当执行事务时,显式地在开始事务之前打开连接,并在提交之后关闭连接。例如:

'Visual Basic Public Sub RunSqlTransaction(da As SqlDataAdapter, myConnection As SqlConnection, ds As DataSet) myConnection.Open() Dim myTrans As SqlTransaction = myConnection.BeginTransaction() myCommand.Transaction = myTrans Try da.Update(ds) myTrans.Commit() Console.WriteLine("Update successful.") Catch e As Exception Try myTrans.Rollback() Catch ex As SqlException If Not myTrans.Connection Is Nothing Then Console.WriteLine("An exception of type " & ex.GetType().ToString() & _ " was encountered while attempting to roll back the transaction.") End If End Try Console.WriteLine("An exception of type " & e.GetType().ToString() & " was encountered.") Console.WriteLine("Update failed.") End Try myConnection.Close() End Sub //C# public void RunSqlTransaction(SqlDataAdapter da, SqlConnection myConnection, DataSet ds) { myConnection.Open(); SqlTransaction myTrans = myConnection.BeginTransaction(); myCommand.Transaction = myTrans; try { da.Update(ds); myCommand.Transaction.Commit(); Console.WriteLine("Update successful."); } catch(Exception e) { try { myTrans.Rollback(); } catch (SqlException ex) { if (myTrans.Connection != null) { Console.WriteLine("An exception of type " + ex.GetType() + " was encountered while attempting to roll back the transaction."); } } Console.WriteLine(e.ToString()); Console.WriteLine("Update failed."); } myConnection.Close(); }

始终关闭 Connection 和 DataReader

完成对 ConnectionDataReader 对象的使用后,总是显式地关闭它们。尽管垃圾回收最终会清除对象并因此释放连接和其他托管资源,但垃圾回收仅在需要时执行。因此,确保任何宝贵的资源被显式释放仍然是您的责任。并且,没有显式关闭的 Connections 可能不会返回到池中。例如,一个超出作用范围却没有显式关闭的连接,只有当池大小达到最大并且连接仍然有效时,才会被返回到连接池中

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wjfxwj.html