SqlConnection 和 SqlDataReader 的复用
Posted
技术标签:
【中文标题】SqlConnection 和 SqlDataReader 的复用【英文标题】:Reuse of SqlConnection and SqlDataReader 【发布时间】:2012-04-26 04:20:01 【问题描述】:如果我想在不同的表上运行多个 SELECT 查询,我可以对所有表使用相同的 SqlDataReader 和 SqlConnection 吗?以下是明智的吗? (我输入得很快,所以它缺少 try/catch):
mysqlCommand myCommand = new MySqlCommand("SELECT * FROM table1", myConnection);
myConnection.Open();
SqlDataReader myDataReader = myCommand.ExecuteReader();
while(myReader.Read())
//Perform work.
myCommand.commandText = "SELECT * FROM table2";
myReader = myCommand.ExecuteReader();
while(myReader.Read())
//Perform more work
myReader.Close();
myConnection.Close();
非常感谢。
【问题讨论】:
你应该考虑使用实体框架。 也许有帮助:***.com/questions/9705637/… 你上面的代码有错误吗?如果没有,那肯定没问题。 你不要重复使用阅读器,ExecuteReader
会创建一个新阅读器。
【参考方案1】:
您可以对它们中的每一个使用相同的连接,只要您不尝试在不同线程的同一连接上同时执行多个查询。
至于数据阅读器,您实际上并没有重用阅读器,每次调用ExecuteReader
都会返回一个新阅读器的新实例,您所重用的只是保持对阅读器的引用的变量.这里存在一个问题,您只是显式地关闭了最后一个阅读器,而让第一个阅读器在以后的某个时间被 GC。
您也可以重复使用命令,但请记住,如果您提供参数等。您需要为下一个查询清除它们,除非它们也适用于下一个查询。
您应该使用try/finally
块来确保清理资源,或者在这里快速更改您的代码以使用using
语句来确保资源清理,即使存在阻止其余部分的异常执行的代码。
using (var myConnection = GetTheConnection())
myConnection.Open();
var myCommand = new MySqlCommand("SELECT * FROM table1", myConnection))
using (var myDataReader = myCommand.ExecuteReader())
while(myReader.Read())
//Perform work.
// Reader will be Disposed/Closed here
myCommand.commandText = "SELECT * FROM table2";
using (var myReader = myCommand.ExecuteReader())
while(myReader.Read())
//Perform more work
// Reader will be Disposed/Closed here
// Connection will be Disposed/Closed here
注意:GetTheConnection
只是用于获取连接实例的机制的占位符函数。
【讨论】:
谢谢。所以我想我只需要在每次执行后关闭阅读器对象。 实际上我正在为 SqlCommand 提供参数,我想我应该使用 myCommand.Parameters.Clear()。非常感谢。 @PaulG,根据经验,每当一个类实现 IDisposable 时,您都应该尽早处理它。就读者而言,它们会占用数据库服务器资源,直到它们被关闭或处置,因此您希望在完成它们后立即处置它们。现在我看到你在使用 MySQL,所以我不知道那里的资源使用情况,但是对于基于服务器的 DBMS 系统,如 Oracle 或 SQL Server,情况就是这样,你应该始终假设是这种情况。【参考方案2】:我通常使用适配器,所以我对读者的细节生疏,但我认为你在正确的轨道上。
您的代码中需要注意的一点是,每次调用 ExecuteReader
都应该生成一个新的数据读取器。您可能正在重用变量名称,但对现有阅读器的引用将被丢弃,并在每次调用时被新的阅读器替换。重点是,在使用 ExecuteReader 获取新的阅读器之前关闭之前的阅读器。
【讨论】:
以上是关于SqlConnection 和 SqlDataReader 的复用的主要内容,如果未能解决你的问题,请参考以下文章
SqlCommand.CommandTimeout 和 SqlConnection.ConnectionTimeout 有啥区别?
c#是不是关闭sqlconnection和sqldatareader?
如何判断SqlConnection是否附加了SqlDataReader?
using (SqlConnection connection = new SqlConnection(connectionString))