C#学习教程:在ExecuteReader()中使用CommandBehavior.CloseConnection有什么用/优势将其作为参数传递给com.ExecuteReader(CommandBehavior.CloseConnection)的用途/好处?从数据读取器读取时需要打开连接,并希望尽快关闭。通过在调用ExecuteReader时指定CommandBehavior.CloseConnection,您可以确保您的代码在关闭数据读取器时关闭连接。但是你应该已经立即处理你的连接(而不是仅仅关闭它们),在这种情况下,这样做最多只能带来边际(几乎肯定无法衡量)的好处。例如,此代码立即关闭其连接(并执行处理它所需的任何其他工作),而无需指定命令行为:using(SqlConnectionconnection=newSqlConnection(connectionString)))){connection.Open();using(SqlDataReaderreader=command.ExecuteReader()){while(reader.Read())//Dosomethingwiththerows}}在创建连接但返回IDataReader的函数中使用CommandBehavior.CloseConnection。在创建读取器之前,在处理IDbConnection异常时要非常小心:IDataReaderReadAll(){varconnection=newSqlConnection(connectionString);尝试{connection.Open();varcommand=connection.CreateCommand();command.CommandText="SELECT*FROMmytable";varresult=command.ExecuteReader(CommandBehavior.CloseConnection);连接=空;//不要释放连接。返回结果;}finally{if(connection!=null)connection.Dispose();如果你不这样做,那么当你在循环中重复使用连接时,连接将保持“打开”状态,直到垃圾收集器将其捡起,然后它会被释放回ADO.net连接池中重用。这意味着每次通过循环,“打开”连接的代码将无法再次重用相同的代码(它还没有被释放回池中)。因此,对于每个连续的循环迭代,ADO都需要从头开始创建另一个连接,最终,您可能会用完所有可用连接。根据GC关闭它所花的时间,您可能已经经历了大量循环迭代,为每个循环迭代创建一个新的不必要的连接,而所有那些未关闭和未使用的连接就在那里。如果您使用CommandBehavior.CloseConnection,在每个循环中,您将连接释放回池中,下一次迭代可以重用它。因此,您的流程将运行得更快,并且可以通过更少的连接逃脱。我建议阅读有关CommandBehaviour枚举的MSDN文档:CloseConnection-执行命令时,关联的Connection对象在关联的DataReader对象关闭时关闭。将此与其他枚举项进行比较。我发现CommandBehavior.CloseConnection的最佳用途是当您想要编写足够灵活的代码以便在事务中使用时(这意味着所有查询都具有共享连接)。考虑:publicDbDataReaderGetReader(DbCommandcmd,boolclose=true){if(close)returncmd.ExecuteReader(CommandBehavior.CloseConnection);返回cmd.ExecuteReader();如果您将读取操作作为较大事务的一部分运行,则需要将false传递给此方法。无论哪种情况,您仍应使用using语句进行实际读取。不在事务中:using(varreader=GetReader(cmd,true)){while(reader.Read())...}在事务中,可能检查记录是否存在:boolexists=false;使用(varreader=GetReader(cmd,false)){如果(reader.Read())存在=reader.GetBoolean(0);}第一个示例将关闭阅读器和连接。第二个(事务性的)仍将关闭阅读器,但不会关闭连接。Re:CommandBehavior.CloseConnection的优点是什么?当您不一定要检索和具体化查询将以其他方式返回的所有数据时,长寿命数据读取器很有用。虽然您的应用程序可以直接保留对长期连接的引用,但这可能会导致混乱的架构,其中数据层依赖项(例如ISqlConnection“ISqlConnection”进入应用程序的业务和表示问题。延迟数据检索(即仅在需要时检索数据)好处是调用者可以继续请求更多数据,直到他们的数据需求得到满足——这在需要分页数据或延迟评估直到满足某些条件的情况下很常见。在胖客户端长期连接/延迟数据检索实践可以说在传统架构中更为常见,例如,用户可以在保持连接打开的同时滚动浏览数据,但在现代代码中仍然存在这种用法。这里有一些权衡:同时在读取器(和连接)期间需要应用程序/客户端的内存和网络资源开销,并在RDBMS数据库端维护“状态”(缓冲区)(甚至游标,如果执行使用的PROC)cursors),还有以下好处:防止IDataReader流入您的应用程序当今大多数应用程序都将数据访问问题包装在Repository模式中,或者使用ORM来抽象数据访问——这通常会导致数据检索返回Entity对象而不是整个该应用程序使用低级IDataReaderAPI在本机工作。幸运的是,仍然可以使用延迟生成器(即返回IEnumerable并仍然保持对DataReader(以及连接)生命周期的控制的方法,使用这样的模式(这是一个异步版本,但显然是同步的)代码也将工作,虽然线程更饿)publicTask>LazyQueryAllFoos(){varsqlConn=newSqlConnection(_connectionString);使用(varcmd=newSqlCommand("SELECTId,Col2,...FROMLargeFoos",sqlConn)){awaitmySqlConn.OpenAsync();varreader=cmd.ExecuteReaderAsync(CommandBehavior.CloseConnection);//返回IEnumerable,但尚未实际实现Foos//Reader和Connection保持打开状态,直到调用者完成可枚举returnLazyGenerateFoos(reader);}}//管理foos生命周期的辅助方法privatestaticIEnumerableGenerateFoos(IDataReaderreader){//reader的生命周期限定在IEnumerableusing(reader){while(reader.Read()){yieldreturnnewFoo{ID=转换。ToInt32(读者["Id"]),...};}}//ReaderisClosed+Disposedhere=>连接也关闭了。}注以上为C#学习教程:在ExecuteReader()中使用CommandBehavior.CloseConnec分享的所有内容有什么用处/优势,如果对你有用,需要了解更多C#学习教程,希望大家多多关注~本文收集自网络,并非代表一个位置。如涉及侵权请点击维权联系管理会员删除如需转载请注明出处:
