.NET深入学习笔记(1):DataSet和SqlDataReader性能差异深入剖析与测试(2)

protected   virtual   int  Fill(DataSet dataSet,  string  srcTable, IDataReader dataReader,  int  startRecord,  int  maxRecords)
{
    
int  num;
    IntPtr ptr;
    Bid.ScopeEnter(
out  ptr,  " <comm.DataAdapter.Fill|API> %d#, dataSet, srcTable, dataReader, startRecord, maxRecords\n " this .ObjectID);
    
try
    {
        
if  (dataSet  ==   null )
        {
            
throw  ADP.FillRequires( " dataSet " );
        }
        
if  (ADP.IsEmpty(srcTable))
        {
            
throw  ADP.FillRequiresSourceTableName( " srcTable " );
        }
        
if  (dataReader  ==   null )
        {
            
throw  ADP.FillRequires( " dataReader " );
        }
        
if  (startRecord  <   0 )
        {
            
throw  ADP.InvalidStartRecord( " startRecord " , startRecord);
        }
        
if  (maxRecords  <   0 )
        {
            
throw  ADP.InvalidMaxRecords( " maxRecords " , maxRecords);
        }
        
if  (dataReader.IsClosed)
        {
            
return   0 ;
        }
        DataReaderContainer container 
=  DataReaderContainer.Create(dataReader,  this .ReturnProviderSpecificTypes);
        num 
=   this .FillFromReader(dataSet,  null , srcTable, container, startRecord, maxRecords,  null null );
    }
    
finally
    {
        Bid.ScopeLeave(
ref  ptr);
    }
    
return  num;
}
 
另外一个SqlCommand 的ExecuteReader方法最终调用Run方法代码如下:
internal   bool  Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
{
    
if  ((TdsParserState.Broken  ==   this .State)  ||  ( this .State  ==  TdsParserState.Closed))
    {
        
return   true ;
    }
    
bool  flag  =   false ;
Label_0016:
    
if  (stateObj._internalTimeout)
    {
        runBehavior 
=  RunBehavior.Attention;
    }
    
if  ((TdsParserState.Broken  ==   this .State)  ||  ( this .State  ==  TdsParserState.Closed))
    {
        
goto  Label_06DF;
    }
    
byte  token  =  stateObj.ReadByte();
    
if  ((((((token  !=   170 &&  (token  !=   0xab ))  &&  ((token  !=   0xad &&  (token  !=   0xe3 )))  &&  (((token  !=   0xac &&  (token  !=   0x79 ))  &&  ((token  !=   160 &&  (token  !=   0xa1 ))))  &&  ((((token  !=   0x81 &&  (token  !=   0x88 ))  &&  ((token  !=   0xa4 &&  (token  !=   0xa5 )))  &&  (((token  !=   0xa9 &&  (token  !=   0xd3 ))  &&  ((token  !=   0xd1 &&  (token  !=   0xfd )))))  &&  ((((token  !=   0xfe &&  (token  !=   0xff ))  &&  ((token  !=   0x39 &&  (token  !=   0xed )))  &&  (((token  !=   0xae &&  (token  !=   0x7c ))  &&  ((token  !=   120 &&  (token  !=   0xed )))))
    {
        
this ._state  =  TdsParserState.Broken;
        
this ._connHandler.BreakConnection();
        
throw  SQL.ParsingError();
    }
    
int  tokenLength  =   this .GetTokenLength(token, stateObj);
    
switch  (token)
    {
        
case   0xa4 :
            
if  (dataStream  ==   null )
            {
                
this .SkipBytes(tokenLength, stateObj);
            }
            
else
            {
                dataStream.TableNames 
=   this .ProcessTableName(tokenLength, stateObj);
            }
            
goto  Label_06AF;

        
case   0xa5 :
            
if  (dataStream  ==   null )
            {
                
this .SkipBytes(tokenLength, stateObj);
            }
            
else
            {
                _SqlMetaDataSet metaData 
=   this .ProcessColInfo(dataStream.MetaData, dataStream, stateObj);
                dataStream.SetMetaData(metaData, 
false );
                dataStream.BrowseModeInfoConsumed 
=   true ;
            }
            
goto  Label_06AF;

        
case   0xa9 :
            
this .SkipBytes(tokenLength, stateObj);
            
goto  Label_06AF;

        
case   170 :
        
case   0xab :
        {
            
if  (token  ==   170 )
            {
                stateObj._errorTokenReceived 
=   true ;
            }
            SqlError error 
=   this .ProcessError(token, stateObj);
            
if  (RunBehavior.Clean  ==  (RunBehavior.Clean  &  runBehavior))
            {
                
if  (error.Class  >=   20 )
                {
                    
this .Errors.Add(error);
                }
            }
            
else   if  ((( this ._connHandler  !=   null &&  ( this ._connHandler.Connection  !=   null ))  &&  ( this ._connHandler.Connection.FireInfoMessageEventOnUserErrors  &&  (error.Class  <=   0x10 )))
            {
                
this .FireInfoMessageEvent(stateObj, error);
            }
            
else   if  (error.Class  <   11 )
            {
                
this .Warnings.Add(error);
            }
            
else   if  (error.Class  <=   0x10 )
            {
                
this .Errors.Add(error);
                
if  ((dataStream  !=   null &&   ! dataStream.IsInitialized)
                {
                    runBehavior 
=  RunBehavior.UntilDone;
                }
            }
            
else
            {
                
this .Errors.Add(error);
                runBehavior 
=  RunBehavior.UntilDone;
            }
            
goto  Label_06AF;
        }
        
case   0xac :
        {
            SqlReturnValue rec 
=   this .ProcessReturnValue(tokenLength, stateObj);
            
if  (cmdHandler  !=   null )
            {
                cmdHandler.OnReturnValue(rec);
            }
            
goto  Label_06AF;
        }
        
case   0xad :
        {
            SqlLoginAck ack 
=   this .ProcessLoginAck(stateObj);
            
this ._connHandler.OnLoginAck(ack);
            
goto  Label_06AF;
        }
        
case   0x88 :
        {
            
if  (stateObj._cleanupAltMetaDataSetArray  ==   null )
            {
                stateObj._cleanupAltMetaDataSetArray 
=   new  _SqlMetaDataSetCollection();
            }
            _SqlMetaDataSet altMetaDataSet 
=   this .ProcessAltMetaData(tokenLength, stateObj);
            stateObj._cleanupAltMetaDataSetArray.Add(altMetaDataSet);
            
if  (dataStream  !=   null )
            {
                dataStream.SetAltMetaDataSet(altMetaDataSet, 
0x88   !=  stateObj.PeekByte());
            }
            
goto  Label_06AF;
        }
        
case   0x79 :
        {
            
int  status  =  stateObj.ReadInt32();
            
if  (cmdHandler  !=   null )
            {
                cmdHandler.OnReturnStatus(status);
            }
            
goto  Label_06AF;
        }
        
case   0x81 :
            
if  (tokenLength  !=   0xffff )
            {
                stateObj._cleanupMetaData 
=   this .ProcessMetaData(tokenLength, stateObj);
            }
            
else   if  (cmdHandler  !=   null )
            {
                stateObj._cleanupMetaData 
=  cmdHandler.MetaData;
            }
            
if  (dataStream  !=   null )
            {
                
byte  num5  =  stateObj.PeekByte();
                dataStream.SetMetaData(stateObj._cleanupMetaData, (
0xa4   ==  num5)  ||  ( 0xa5   ==  num5));
            }
            
else   if  (bulkCopyHandler  !=   null )
            {
                bulkCopyHandler.SetMetaData(stateObj._cleanupMetaData);
            }
            
goto  Label_06AF;

        
case   0xd1 :
            
if  (bulkCopyHandler  ==   null )
            {
                
if  (RunBehavior.ReturnImmediately  !=  (RunBehavior.ReturnImmediately  &  runBehavior))
                {
                    
this .SkipRow(stateObj._cleanupMetaData, stateObj);
                }
                
break ;
            }
            
this .ProcessRow(stateObj._cleanupMetaData, bulkCopyHandler.CreateRowBuffer(), bulkCopyHandler.CreateIndexMap(), stateObj);
            
break ;

        
case   0xd3 :
            
if  (RunBehavior.ReturnImmediately  !=  (RunBehavior.ReturnImmediately  &  runBehavior))
            {
                
int  num8  =  stateObj.ReadUInt16();
                
this .SkipRow(stateObj._cleanupAltMetaDataSetArray[num8], stateObj);
            }
            flag 
=   true ;
            
goto  Label_06AF;

        
case   0xe3 :
        {
            SqlEnvChange[] changeArray 
=   this .ProcessEnvChange(tokenLength, stateObj);
            
for  ( int  i  =   0 ; i  <  changeArray.Length; i ++ )
            {
                
if  (changeArray[i]  ==   null )
                {
                    
continue ;
                }
                
switch  (changeArray[i].type)
                {
                    
case   8 :
                    
case   11 :
                        
this ._currentTransaction  =   this ._pendingTransaction;
                        
this ._pendingTransaction  =   null ;
                        
if  ( this ._currentTransaction  ==   null )
                        {
                            
break ;
                        }
                        
this ._currentTransaction.TransactionId  =  changeArray[i].newLongValue;
                        
goto  Label_048E;

                    
case   9 :
                    
case   12 :
                    
case   0x11 :
                        
this ._retainedTransactionId  =   0L ;
                        
goto  Label_04D1;

                    
case   10 :
                        
goto  Label_04D1;

                    
default :
                        
goto  Label_0551;
                }
                TransactionType type 
=  ( 8   ==  changeArray[i].type)  ?  TransactionType.LocalFromTSQL : TransactionType.Distributed;
                
this ._currentTransaction  =   new  SqlInternalTransaction( this ._connHandler, type,  null , changeArray[i].newLongValue);
            Label_048E:
                
if  (( this ._statistics  !=   null &&   ! this ._statisticsIsInTransaction)
                {
                    
this ._statistics.SafeIncrement( ref   this ._statistics._transactions);
                }
                
this ._statisticsIsInTransaction  =   true ;
                
this ._retainedTransactionId  =   0L ;
                
continue ;
            Label_04D1:
                
if  ( this ._currentTransaction  !=   null )
                {
                    
if  ( 9   ==  changeArray[i].type)
                    {
                        
this ._currentTransaction.Completed(TransactionState.Committed);
                    }
                    
else   if  ( 10   ==  changeArray[i].type)
                    {
                        
if  ( this ._currentTransaction.IsDistributed  &&   this ._currentTransaction.IsActive)
                        {
                            
this ._retainedTransactionId  =  changeArray[i].oldLongValue;
                        }
                        
this ._currentTransaction.Completed(TransactionState.Aborted);
                    }
                    
else
                    {
                        
this ._currentTransaction.Completed(TransactionState.Unknown);
                    }
                    
this ._currentTransaction  =   null ;
                }
                
this ._statisticsIsInTransaction  =   false ;
                
continue ;
            Label_0551:
                
this ._connHandler.OnEnvChange(changeArray[i]);
            }
            
goto  Label_06AF;
        }
        
case   0xfd :
        
case   0xfe :
        
case   0xff :
            
this .ProcessDone(cmdHandler, dataStream,  ref  runBehavior, stateObj);
            
if  ((token  ==   0xfe &&  (cmdHandler  !=   null ))
            {
                cmdHandler.OnDoneProc();
            }
            
goto  Label_06AF;

        
case   0xed :
            
this .ProcessSSPI(tokenLength);
            
goto  Label_06AF;

        
default :
            
goto  Label_06AF;
    }
    
if  ( this ._statistics  !=   null )
    {
        
this ._statistics.WaitForDoneAfterRow  =   true ;
    }
    flag 
=   true ;
Label_06AF:
    
if  ((stateObj._pendingData  &&  (RunBehavior.ReturnImmediately  !=  (RunBehavior.ReturnImmediately  &  runBehavior)))  ||  (( ! stateObj._pendingData  &&  stateObj._attentionSent)  &&   ! stateObj._attentionReceived))
    {
        
goto  Label_0016;
    }
Label_06DF:
    
if  ( ! stateObj._pendingData  &&  ( this .CurrentTransaction  !=   null ))
    {
        
this .CurrentTransaction.Activate();
    }
    
if  (stateObj._attentionSent  &&  stateObj._attentionReceived)
    {
        stateObj._attentionSent 
=   false ;
        stateObj._attentionReceived 
=   false ;
        
if  ((RunBehavior.Clean  !=  (RunBehavior.Clean  &  runBehavior))  &&   ! stateObj._internalTimeout)
        {
            
this .Errors.Add( new  SqlError( 0 0 11 this ._server, SQLMessage.OperationCancelled(),  "" 0 ));
        }
    }
    
if  (( this ._errors  !=   null ||  ( this ._warnings  !=   null ))
    {
        
this .ThrowExceptionAndWarning(stateObj);
    }
    
return  flag;
}
 
     我已经使用Reflector查看了SQLDataAdapter类型的Fill方法以及SqlCommand.ExecuteReader 方法代码。确实有使用DataReader的地方。他们是真正负责处理查询并装在数据。DataReader和DataSet应该都是数据容器。做个类比的话,应该是茶壶和茶杯的关系。至于查询数据,除了取决于容器,还和具体负责查询和装载数据的类有关系。 我文章的标题,应该说是有问题的,这种比较忽略了一个数据查询和装载的过程。有不合理的地方。现在更正。
本文出自 51CTO.COM技术博客

你可能感兴趣的:(数据库,职场,null,休闲)