.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应该都是数据容器。做个类比的话,应该是茶壶和茶杯的关系。至于查询数据,除了取决于容器,还和具体负责查询和装载数据的类有关系。 我文章的标题,应该说是有问题的,这种比较忽略了一个数据查询和装载的过程。有不合理的地方。现在更正。



 本文转自 frankxulei 51CTO博客,原文链接:http://blog.51cto.com/frankxulei/321001,如需转载请自行联系原作者



相关文章
|
前端开发 程序员 开发工具
基于.Net开发的对比Html效果差异的开源项目
基于.Net 4.5开发的对比Html文件、片段效果差异的项目。两份Html效果不一样的地方会通过颜色、删除线、背景色分别标记出来。
214 0
基于.Net开发的对比Html效果差异的开源项目
|
存储 SQL 数据库连接
浅谈ADO.NET中的对象——Connection、Command、DataReader、DataAdapter、DataSet、DataTable
可能是当初没有好好总结的缘故,学习.NET以来,对ADO.NET中的对象一直有些模糊,今天重新回顾了一下,通过查资料,总结,结合自己的观点整理一下ADO.NET中Connection、Command、DataReader、DataAdapter、
浅谈ADO.NET中的对象——Connection、Command、DataReader、DataAdapter、DataSet、DataTable
|
Web App开发 网络协议 安全
一起谈.NET技术,HTTP协议及POST与GET操作差异,C#中如何使用POST、GET等
引言 HTTP协议我想任何IT人士都耳熟能详了,大家都能说出个所以然来。但是如果我问你HTTP协议的请求方法有哪些?POST与GET的差异?GET或POST传送数据量的大小有限制吗?HTTP响应的状态有哪些?以及在C#中你如何使用?如果你不能清楚地回答其中的大部分问题,那么这篇文章就是为你准备的!大纲如下: 1、HTTP概述 1.
1395 0
|
XML 存储 数据格式
一起谈.NET技术,XML与DataSet对象的关系
  在.NET Framework 中,经常使用XML 作为存储和传输各种数据的格式。DataSet 中的数据可以转换成XML 的形式来表示和存储。我们可以使用XML 对象同步和转换DataSet 的数据,而DataSet 也可以存储和传输XML 格式的数据。
973 0
|
.NET
一起谈.NET技术,OnLoad与Page_Load的差异分析
  记得最开始学习ASP.NET的时候,我们就被告知:Page_Load方法里面可以写页面加载的代码。   于是我们就懵懵懂懂写了很长时间的Page_Load方法。最近回过头思考,为什么一个普通的方法,能被自动调用呢?于是就得知了AutoEventWireup属性。
727 0
|
安全
.NET Core中延迟单例另一种写法【.NET Core和.NET Framework的beforefieldinit差异】
1.BeforeFieldInit是什么    前段时间在反编译代码时无意间看到在类中有一个BeforeFieldInit特性,处于好奇的心态查了查这个特性,发现这是一个关于字段初始化时间的特性【提前初始化字段】,下面先来看一下这个特性在.
1812 0