Be a programmer

Live with passion....
  首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

The Provider Design Pattern and Data Access Component - III

Posted on 2006-06-07 09:55  Programmer  阅读(1768)  评论(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 );
  •