1)
在使用SqlDataReader时,关联的SqlConnection正忙于为SqlDataReader提供服务,除了关闭SqlConnection之外,不能对SqlConnection执行任何其他操作。在调用SqlDataReader的Close方法之前就是这种情况。例如,在调用Close之前,无法检索输出参数。
如果上述说法属实,那么为什么以下方法能够在读取器关闭之前从输出参数中检索值:
public int Something()
{
using (SqlConnection con = new SqlConnection(this.ConnectionString))
{
SqlCommand cmd = new SqlCommand("some_procedure", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@ID", SqlDbType.Int).Direction = ParameterDirection.Output;
con.Open();
cmd.ExecuteReader();
return (int)cmd.Parameters["@ID"].Value;
}
}
2)
您可以重置CommandText属性并重用SqlCommand对象。但是,必须先关闭SqlDataReader,然后才能执行新命令或上一个命令。
为什么在执行新命令之前必须关闭sqldatareader?
感谢名单
答案 0 :(得分:3)
在第一个问题中,您正在执行NonQuery - 因此在获取输出参数之前没有要关闭的阅读器。
对于第二个问题,你就是这样做的。当一个阅读器打开时,该命令不会让你打电话给另一个阅读器。
答案 1 :(得分:0)
请原谅我直接陈述,但你似乎没有清楚地了解数据阅读器(System.Data.IDataReader
)到底是什么。所以,让我演示一下:
using System;
using System.Data;
using System.Data.SqlClient;
string connectionString = "...";
// create and open a DB connection:
using (IDbConnection connection = new SqlConnection(connectionString))
{
connection.Open();
// create a command object:
using (IDbCommand query = connection.CreateCommand())
{
query.CommandType = CommandType.Text;
query.CommandText = "SELECT ID, Name, Birthdate FROM SomeTable";
// execute the query and retrieve a data reader object:
using (IDataReader reader = query.ExecuteReader())
{
// the data reader is now used to read the query result:
while (reader.Read())
{
int id = reader.GetInt32(0);
string name = reader.GetString(1);
DateTime birthdate = reader.GetDateTime(0);
}
}
// at this point, the data reader object has been disposed.
// the DB connection can now be used again, e.g. by issuing
// another query:
command.CommandText = "SELECT COUNT(*) FROM SomeOtherTable";
...
}
}
注意:我已经避免使用var
,因此您可以确切了解所涉及的类型。 (还要注意,我使用的主要是IDbConnection
等接口类型,而不是SqlConnection
等具体实现类。这使得代码更容易适应其他RDBMS。)
您现在可以看到,在您的代码中,您从未真正使用过数据读取器。因此,您的代码工作正常,因为从来没有一个开放的数据读取器可以首先“阻止”您的数据库连接。