The Provider Design Pattern and Data Access Component - III
Posted on 2006-06-07 09:55 Programmer 阅读(1771) 评论(4) 编辑 收藏 举报SqlCommand.ExecuteReader & ParameterDirection.ReturnValue
I've made a great mistake when using the SqlCommand.ExecuteReader method. As we know, the ParameterDirection.ReturnValue parameters cannot be accessed if the associated SqlDataReader is still open. So, the return value will always be zero by calling SqlDataProviderBase.RunDataReader(string procName, SqlParameter[] parameters, out int returnValue).
I wrote a new class to resolve this bug. This class was named SqlDataReaderHolder.
The SqlDataProviderBase.RunDataReader method has to be rewritten too.
- protected SqlDataReaderHolder RunDataReader(string procName, SqlParameter[] parameters, bool requireReturnValue)
- {
- SqlConnectionHolder connectionHolder;
- SqlCommand sqlCommand;
- SqlDataReader dr;
- // Creates an active sql connection
- using ( connectionHolder = GetConnectionHolder() ) {
- connectionHolder.AutoClose = false;
- // Creates a SqlCommand
- using ( sqlCommand = BuildSQLCommand(
- connectionHolder, procName, parameters, requireReturnValue) ) {
- if ( _underTrans ) {
- // If the SQL query is a part of a transaction operation,
- // the associated SqlConnection won't be closed after the SqlDataReader is closed.
- dr = sqlCommand.ExecuteReader(CommandBehavior.Default);
- }
- else {
- // Otherwise, the associated SqlConnection must be closed while the SqlDataReader is closing.
- dr = sqlCommand.ExecuteReader(CommandBehavior.CloseConnection);
- }
- if ( requireReturnValue ) {
- return new SqlDataReaderHolder(dr, sqlCommand.Parameters[s_returnValueParamName]);
- }
- else {
- return new SqlDataReaderHolder(dr);
- }
- }
- }
- }
Sample code:
- SqlDataProviderBase dataProvider;
- SqlDataReaderHolder holder;
- SqlParameter[] parameters;
- // Creates parameters
- parameters = new SqlParameter[]{
- CreateInputParam("@myParam", SqlDbType.Int, 10),
- ...
- };
- // Executes the database query
- using( holder = RunDataReader("dbo.myStoredProc", parameters, true) ){
- while( holder.Reader.Read() ){
- // do something...
- }
- }
- // Gets the return value here
- Console.Write( "The return value is {0}.", holder.ReturnValue );