.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,如需转载请自行联系原作者



相关文章
|
2月前
|
测试技术 持续交付 API
深入挖掘探索.NET单元测试
【10月更文挑战第11天】
48 2
|
3天前
|
算法 Java 测试技术
使用 BenchmarkDotNet 对 .NET 代码进行性能基准测试
使用 BenchmarkDotNet 对 .NET 代码进行性能基准测试
32 13
|
24天前
|
算法 Java 测试技术
Benchmark.NET:让 C# 测试程序性能变得既酷又简单
Benchmark.NET是一款专为 .NET 平台设计的性能基准测试框架,它可以帮助你测量代码的执行时间、内存使用情况等性能指标。它就像是你代码的 "健身教练",帮助你找到瓶颈,优化性能,让你的应用跑得更快、更稳!希望这个小教程能让你在追求高性能的路上越走越远,享受编程带来的无限乐趣!
78 13
|
1月前
|
开发框架 安全 .NET
在数字化时代,.NET 技术凭借跨平台兼容性、丰富的开发工具和框架、高效的性能及强大的安全稳定性,成为软件开发的重要支柱
在数字化时代,.NET 技术凭借跨平台兼容性、丰富的开发工具和框架、高效的性能及强大的安全稳定性,成为软件开发的重要支柱。它不仅加速了应用开发进程,提升了开发质量和可靠性,还促进了创新和业务发展,培养了专业人才和技术社区,为软件开发和数字化转型做出了重要贡献。
30 5
|
1月前
|
传感器 人工智能 供应链
.NET开发技术在数字化时代的创新作用,从高效的开发环境、强大的性能表现、丰富的库和框架资源等方面揭示了其关键优势。
本文深入探讨了.NET开发技术在数字化时代的创新作用,从高效的开发环境、强大的性能表现、丰富的库和框架资源等方面揭示了其关键优势。通过企业级应用、Web应用及移动应用的创新案例,展示了.NET在各领域的广泛应用和巨大潜力。展望未来,.NET将与新兴技术深度融合,拓展跨平台开发,推动云原生应用发展,持续创新。
43 4
|
1月前
|
机器学习/深度学习 人工智能 Cloud Native
在数字化时代,.NET 技术凭借其跨平台兼容性、丰富的类库和工具集以及卓越的性能与效率,成为软件开发的重要平台
在数字化时代,.NET 技术凭借其跨平台兼容性、丰富的类库和工具集以及卓越的性能与效率,成为软件开发的重要平台。本文深入解析 .NET 的核心优势,探讨其在企业级应用、Web 开发及移动应用等领域的应用案例,并展望未来在人工智能、云原生等方面的发展趋势。
42 3
|
1月前
|
开发框架 安全 Java
.NET技术的独特魅力与优势,涵盖高效的开发体验、强大的性能表现、高度的可扩展性及丰富的生态系统等方面,展示了其在软件开发领域的核心竞争力
本文深入探讨了.NET技术的独特魅力与优势,涵盖高效的开发体验、强大的性能表现、高度的可扩展性及丰富的生态系统等方面,展示了其在软件开发领域的核心竞争力。.NET不仅支持跨平台开发,具备出色的安全性和稳定性,还能与多种技术无缝集成,为企业级应用提供全面支持。
36 3
|
1月前
|
人工智能 Java 编译器
.NET 9 发布 性能提升、AI 支持与全方位改进
【11月更文挑战第5天】.NET 9 引入了多项改进,包括性能提升、AI 支持和全方位功能优化。性能方面,编译器增强、服务器 GC 优化、矢量化和硬件支持等提升了执行效率。AI 方面,新增学习材料、合作伙伴生态、原生支持和生成式 AI 集成。此外,.NET Aspire 组件升级、编程语言新功能和开发工具更新进一步提升了开发体验。
|
2月前
|
测试技术
自动化测试项目学习笔记(五):Pytest结合allure生成测试报告以及重构项目
本文介绍了如何使用Pytest和Allure生成自动化测试报告。通过安装allure-pytest和配置环境,可以生成包含用例描述、步骤、等级等详细信息的美观报告。文章还提供了代码示例和运行指南,以及重构项目时的注意事项。
304 1
自动化测试项目学习笔记(五):Pytest结合allure生成测试报告以及重构项目
|
2月前
|
测试技术 API 开发者
精通.NET单元测试:MSTest、xUnit、NUnit全面解析
【10月更文挑战第15天】本文介绍了.NET生态系统中最流行的三种单元测试框架:MSTest、xUnit和NUnit。通过示例代码展示了每种框架的基本用法和特点,帮助开发者根据项目需求和个人偏好选择合适的测试工具。
48 3