调用多个“;SQL数据读取器”;s在C#中
本文关键字:数据 SQL 调用 读取 | 更新日期: 2023-09-27 18:29:53
我调用ExecuteReader();
来获取数据,然后我需要用另一个查询来获取另一个数据。我的结构一直是这样的:
class SomeClass
{
public static void Main(String[] args)
{
SqlConnection sqlConn = new SqlConnection();
sqlConn.ConnectionString = "some connection string"
SqlCommand SQLCmd = new SqlCommand();
SQLCmd.CommandText = "some query";
SQLCmd.Connection = sqlConn;
sqlConn.Open();
sqlReader = SQLCmd.ExecuteReader();
while (sqlReader.Read())
{
//some stuff here
}
sqlReader.Dispose();
sqlReader.Close();
sqlConn.Close();
SQLCmd.CommandText = "another query";
sqlConn.Open();
sqlReader = SQLCmd.ExecuteReader();
while (sqlReader.Read())
{
//some other stuff here
}
sqlReader.Dispose();
sqlReader.Close();
sqlConn.Close();
}
}
它们共享相同的连接字符串。他们还能分享什么?他们能共享相同的sqlConn.Open();
吗?资源分配和避免错误的正确方法是什么?
顺便说一句,它能正常工作。提前谢谢。
我就是这样写的:
class SomeClass
{
public static void Main(String[] args)
{
using (SqlConnection sqlConn = new SqlConnection("some connection string"))
{
sqlConn.Open();
using (SqlCommand comm = new SqlCommand("some query", conn))
using (var sqlReader = comm.ExecuteReader())
{
while (sqlReader.Read())
{
//some stuff here
}
}
using (SqlCommand comm = new SqlCommand("some query", conn))
using (var sqlReader = comm.ExecuteReader())
{
while (sqlReader.Read())
{
//some other stuff here
}
}
}
}
}
using
语句在块完成时处理项目的处理。至于共享内容,您可以在命令之间打开连接。
要处理掉所有这些,最重要的是连接,但如果一个项是IDisposable
,我倾向于遵守using
语句,而不管它在后台实际做了什么(这可能会因为它是一个实现细节而发生变化)。
别忘了,还有来自单个命令和单个读取器的多个活动结果集(如本答案所示),您可以在其中将读取器推进到下一个结果集。
我对如何写这一切的回答稍微轻率一点:
return connection.Query<T>(procedureName, param, commandType: CommandType.StoredProcedure);
使用Dapper;-)
正如我的评论中所暗示的,如果可能,将两个查询合并为一个,然后(如果它仍然产生多个结果集),使用NextResult
继续前进。
偷走亚当的结构,但有了改变:
class SomeClass
{
public static void Main(String[] args)
{
using (SqlConnection sqlConn = new SqlConnection("some connection string"))
{
sqlConn.Open();
using (SqlCommand comm = new SqlCommand("some query; some other query;", conn))
using (var sqlReader = comm.ExecuteReader())
{
while (sqlReader.Read())
{
//some stuff here
}
if(sqlReader.NextResult())
{
while (sqlReader.Read())
{
//some other stuff here
}
}
}
}
}
}
正确的方法是将SqlConnection
s和SqlCommand
s包装在using
-语句中。这将强制在剩下using块时对对象调用Dispose
,即使抛出了Exception。(您当前的代码并非如此。)
中的某些内容
using(var cnn = new SqlConnection("connectionstring")){
cnn.Open();
using(var cmd = new SqlCommand("SELECT 1")){
var reader = cmd.ExecuteReader();
while(reader.Read()) { /* doStuff */ }
}
}
不管采用何种方法,Close
/Dispose
实际上都不会关闭连接,因为连接设置非常昂贵。它只会将连接返回到连接池,并允许其他命令/读取器使用它。
要管理资源,可以使用using
,如下所示…
SQLCmd.CommandText = "some query";
SQLCmd.Connection = sqlConn;
sqlConn.Open();
//using will dispose reader automatically.
using(sqlReader = SQLCmd.ExecuteReader())
{
while (sqlReader.Read())
{
//some stuff here
}
}
//sqlReader.Dispose();
//sqlReader.Close();
//sqlConn.Close();
SQLCmd.CommandText = "another query";
//no need to open connection again.
// sqlConn.Open();
// sqlReader = SQLCmd.ExecuteReader();
using(sqlReader = SQLCmd.ExecuteReader())
{
while (sqlReader.Read())
{
//some stuff here
}
}
//sqlReader.Dispose();
//sqlReader.Close();
//sqlConn.Close();
using
只能用于那些已经实现了IDispose
接口的类。在您的示例中,您还可以将SqlConnection
和SqlCommand
与using代码块一起使用。
使用'using',不需要手动关闭和处理。
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand command = new SqlCommand("spTest", connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("@employeeid", employeeID));
command.CommandTimeout = 5;
command.ExecuteNonQuery();
}
每次需要都打开一个新的连接是最佳做法。ADO.net使用连接池管理连接。http://msdn.microsoft.com/it-it/library/8xx3tyca(v=vs.110).aspx
不过不要忘记您的try-catch语句:)
class SomeClass
{
public static void Main(String[] args)
{
using (SqlConnection sqlConn = new SqlConnection("some connection string"))
{
try{
sqlConn.Open();
using (SqlCommand comm = new SqlCommand("some query", conn))
using (var sqlReader = comm.ExecuteReader())
{
while (sqlReader.Read())
{
//some stuff here
}
}
using (SqlCommand comm = new SqlCommand("some query", conn))
using (var sqlReader = comm.ExecuteReader())
{
while (sqlReader.Read())
{
//some other stuff here
}
}
}
catch()
{
// Do exception catching here or rollbacktransaction if your using begin transact
}
finally
{
sqlConn.Close();
}
}
}
}