C# 修复错误-已存在与此命令关联的打开的DataReader,必须先关闭该命令
在C#脚本中,我尝试读取带有SqlDataReader对象的表,然后删除该表。 其实很简单 这是我使用的代码-C# 修复错误-已存在与此命令关联的打开的DataReader,必须先关闭该命令,c#,.net,C#,.net,在C#脚本中,我尝试读取带有SqlDataReader对象的表,然后删除该表。 其实很简单 这是我使用的代码- SqlConnection conn = getAWorkingDbConnection();//Always gives me a good connection SqlCommand sqlCmd = new SqlCommand(); SqlDataReader dataReader; sqlCmd.CommandTimeout = 0; sqlCmd.Connection =
SqlConnection conn = getAWorkingDbConnection();//Always gives me a good connection
SqlCommand sqlCmd = new SqlCommand();
SqlDataReader dataReader;
sqlCmd.CommandTimeout = 0;
sqlCmd.Connection = conn;
sqlCmd.CommandText = "SELECT * FROM GlassTable";
dataReader = sqlCmd.ExecuteReader();
//Code to read rows with SqlDataReader and print them to a file.
sqlCmd.CommandText = "DROP TABLE GlassTable";
sqlCmd.ExecuteReader();// BAD !!!
我得到这个错误-
System.InvalidOperationException:已存在关联的打开的DataReader
此命令必须先关闭
我看到了ExecuteReader方法的API,但它没有回答我的问题。
为什么会发生此错误以及如何修复它
谢谢。您的问题是您没有处理正在使用的对象。出于这个目的,最好总是使用
和结构,因为它可以保证一切都会被处理掉。请尝试以下代码:
sqlCmd.CommandText = "SELECT * FROM GlassTable";
using (dataReader = sqlCmd.ExecuteReader())
{
//Code to read rows with SqlDataReader and print them to a file.
}
此外,对于不返回记录的查询,不必使用ExecuteReader
sqlCmd.CommandText = "DROP TABLE GlassTable";
int recordsAffected = sqlCmd.ExecuteNonQuery();
您需要关闭数据读取器
最快的方法是使用using
语句为您处理数据读取器:
using (var dataReader = sqlCmd.ExecuteReader())
{
//Stuff
}
或者,如果要保留相同的实例,可以在try…finally
块中调用Close()
。使用using
-语句尽快对所有非托管资源进行二次占用:
using(SqlConnection conn = getAWorkingDbConnection())
using (SqlCommand sqlCmd = new SqlCommand("SELECT * FROM GlassTable", conn))
{
sqlCmd.CommandTimeout = 0;
conn.Open();
using (SqlDataReader dataReader = sqlCmd.ExecuteReader())
{
while (dataReader.Read())
{
// do something useful ...
}
}
sqlCmd.CommandText = "DROP TABLE GlassTable";
sqlCmd.ExecuteNonQuery();
}
我不想为此使用任何MARS。请使用新连接创建新命令。但是你能解释为什么火星不行吗?@Steve-嗯,实际上这段代码用在SSIS C#脚本中。我使用SSIS(ETL工具)数据库连接管理器,我怀疑它不允许您使用MARS。如果您自己生成字符串,就可以使用mars。但是,如果你把它从SSIS连接管理器上取下来,可能就不会了。老兄,今晚我的英语不好,读起来会更好吗@Selman22?哦。对这是一个非查询代码不工作。我又犯了同样的错误。@blato您是否确保将所有IDataReader
s放在单独的using块中,并将ExecuteNonQuery()
放在这些块之外?当using
块结束时,读卡器关闭。谢谢tim。我觉得应该有一个,;在使用(SqlConnection conn=getAWorkingDbConnection())@blato:no之后,此使用的范围包括下一次使用,类似于foreach(var obj in seq)foreach(var otherObj in obj.OtherSeq){}
。我可以用{}
来包围它。我喜欢这个以免缩进。谢谢。如果我在第二个“using”中使用SqlCommand sqlCmd=new SqlCommand(),然后在“using”中初始化sqlCmd,可以吗?@blato:可以,如果需要,您甚至可以在using
之前声明它。使用只需确保即使出现错误,IDisposable
也会被释放(这也会关闭连接);使用(sqlCmd=getCommandFromSomewhere()){//在此处使用它}。对吗?