我调用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();
吗?什么是资源分配和避免错误的正确方法?
答案 0 :(得分:4)
这就是我写所有内容的方式:
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
语句处理块完成时处理项目。至于共享内容,您可以在命令之间保持连接打开。
排除所有这一切的最重要的事情就是连接,但如果一个项目是using
而不管它在后台实际做了什么,我倾向于尊重IDisposable
语句(由于是实施细节,因此可能会发生变化。
不要忘记,单个命令和单个阅读器中还有多个活动结果集(as demonstrated in this answer),您可以将阅读器推进到下一个结果集。
<小时/> 对于我如何编写所有这些内容,我略微轻率一点的答案是:
return connection.Query<T>(procedureName, param, commandType: CommandType.StoredProcedure);
使用Dapper; - )
答案 1 :(得分:4)
在我的评论中提到 - 如果可能,将两个查询合并为一个然后(如果它仍然产生多个结果集),使用NextResult
继续前进。
窃取亚当的structure,但随着这种变化:
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
}
}
}
}
}
}
答案 2 :(得分:1)
正确的方法是在SqlConnection
- 语句中包含SqlCommand
和using
。这将强制在使用块时调用对象Dispose
,即使抛出异常也是如此。 (当前代码不是这种情况。)
中的某些内容
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
都不会实际关闭连接,因为连接设置非常昂贵。它只会将连接返回到连接池,并允许其他命令/读者使用它。
答案 3 :(得分:1)
要管理资源,您可以使用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
来使用代码块。
答案 4 :(得分:0)
使用'使用',您无需手动关闭和处理。
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();
}
答案 5 :(得分:0)
每次需要时打开一个新连接是最佳做法。 ADO.net使用连接池来进行连接。 http://msdn.microsoft.com/it-it/library/8xx3tyca(v=vs.110).aspx
答案 6 :(得分:0)
不要忘记你的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();
}
}
}
}