Be a programmer

Live with passion....
posts - 10, comments - 31, trackbacks - 2, articles - 0
   :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

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 );
  •  

Feedback

#1楼   回复  引用  查看    

2006-06-07 10:34 by henry      
既然都是要等到DataReader.Close()后才能获取返回值,那这一步封装意义可在?体现了那些易用性和方便性?

#2楼[楼主]   回复  引用  查看    

2006-06-07 11:02 by Programmer      
@henry

因为整个 DataProviderBase 和 SqlDataProviderBase 类的设计目的之一就是让用户在使用的时候可以忽略事务的处理。比如,同样的一个读取 SqlDataReader 的方法,如果是在事务中的话,在读完 SqlDataReader 后就不能关闭相应的 SqlConnection;而不需要使用事务的就必须要关闭。使用文章中的方法,用户就完全可以忽略掉这一步!

#3楼   回复  引用    

2006-06-07 18:11 by werwe[未注册用户]
:)

#4楼   回复  引用    

2006-06-07 18:11 by werwe[未注册用户]
http://mu1.k6345.cn



发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 419302




相关文章:

相关链接: