Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 修复错误-已存在与此命令关联的打开的DataReader,必须先关闭该命令_C#_.net - Fatal编程技术网

C# 修复错误-已存在与此命令关联的打开的DataReader,必须先关闭该命令

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 =

在C#脚本中,我尝试读取带有SqlDataReader对象的表,然后删除该表。 其实很简单

这是我使用的代码-

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()){//在此处使用它}。对吗?