C# &引用;已经有一个与此命令关联的打开的DataReader,必须先关闭它。”;

C# &引用;已经有一个与此命令关联的打开的DataReader,必须先关闭它。”;,c#,sql,database,connection,reader,C#,Sql,Database,Connection,Reader,我正在开发一个需要连接到另一个数据库以获取数据的应用程序, 为此,我决定使用SqlConnection、reader等 我需要执行一些查询,例如,首先我需要获取某个用户的卡ID,然后我需要通过该卡ID获取一些数据 这是我的密码: #region Connection to another Database SqlConnection sqlConnection1 = new SqlConnection("Data Source=ComputerOne; Initial Catalog=Test

我正在开发一个需要连接到另一个数据库以获取数据的应用程序, 为此,我决定使用SqlConnection、reader等

我需要执行一些查询,例如,首先我需要获取某个用户的卡ID,然后我需要通过该卡ID获取一些数据

这是我的密码:

#region Connection to another Database

SqlConnection sqlConnection1 = new SqlConnection("Data Source=ComputerOne; Initial Catalog=TestDatabase;Integrated Security=False; User ID=test; Password=test123;");
SqlCommand cmd = new SqlCommand();
SqlDataReader reader;

cmd.CommandText = "Select * From Users Where CardID=" + "'" + user.CardID + "'";
cmd.CommandType = CommandType.Text;
cmd.Connection = sqlConnection1;

sqlConnection1.Open();

reader = cmd.ExecuteReader();

string cardID = "";
string quantity="";

while (reader.Read())
{
    cardID = reader["CardID"].ToString();
}
//HOW COULD I WRITE ANOTHER QUERY NOW, FOR EXAMPLE, OK I GOT CARDID NOW GIVE ME SOME OTHER THINGS FROM THAT DATABASE BY THAT cardID
//here I tried to change CommandText and to keep working with reader.. but its not working like this because its throwing me exception mention in question title.

cmd.CommandText = "Select T1.CardID, T2.Title, Sum(T1.Quantity) as Quantity From CardTransactions as T1 JOIN Adds as T2 ON T1.AddsID = T2.AddsID Where T1.CardID =" + cardID + "AND T1.Type = 1 Group By T1.CardID, T2.Title";

reader = cmd.ExecuteReader();

while (reader.Read())
{
    quantity = reader["Quantity"].ToString();
}

// Data is accessible through the DataReader object here.

sqlConnection1.Close();

#endregion 
所以伙计们,我怎么能用这个例子执行一些查询呢

非常感谢!
干杯

您打开的读卡器仍然处于活动状态。您一次只能有一个活动阅读器。您应该使用将所有
Sql…
实例包装在
中,以确保它们正确关闭

using (SqlConnection connection = new SqlConnection(...))
{
    using (SqlDataReader reader = cmd.ExecuteReader())
    {
        // the code using reader
    }
}

嗯。。。您收到错误是因为第一次调用使用的读取器未关闭。在使用完DataReader对象后,应该始终调用Close方法,以确保读取器使用的连接返回到连接池(该连接由该DataReader独占使用)。部分代码:

reader = cmd.ExecuteReader();
try
{
  while(myReader.Read()) 
  {
    while (reader.Read())
    {
        cardID = reader["CardID"].ToString();
    }
}
finally
{
  myReader.Close();
}
...
reader = cmd.ExecuteReader();
try
{
  while(myReader.Read()) 
  {
        reader = cmd.ExecuteReader();

        while (reader.Read())
        {
            quantity = reader["Quantity"].ToString();
        }
  }
}
finally
{
  myReader.Close();
  myConnection.Close();
}

还有。。。作为一个干净的代码规则,用不同的方法(可靠的原则)分离调用。

您的问题是您没有处理正在使用的对象。为此,最好始终使用
结构,因为它可以保证所有内容都将被处理。请尝试以下代码:

SqlConnection sqlConnection1 = new SqlConnection("Data Source=ComputerOne; Initial Catalog=TestDatabase;Integrated Security=False; User ID=test; Password=test123;");
SqlCommand cmd = new SqlCommand();
SqlDataReader reader;
string cardID = "";
string quantity="";

using(sqlConnection1 = new SqlConnection("Data Source=ComputerOne; Initial Catalog=TestDatabase;Integrated Security=False; User ID=test; Password=test123;"))
{
    sqlConnection1.Open();

    using(cmd = new SqlCommand())
    {
        cmd.CommandText = "Select * From Users Where CardID=" + "'" + user.CardID + "'";
        cmd.CommandType = CommandType.Text;
        cmd.Connection = sqlConnection1;

        using(reader = cmd.ExecuteReader())
        {


            while (reader.Read())
            {
                cardID = reader["CardID"].ToString();
            }
        } //reader gets disposed right here
    } //cmd gets disposed right here

    using(cmd = new SqlCommand())
    {
        cmd.CommandText = "Select T1.CardID, T2.Title, Sum(T1.Quantity) as Quantity From CardTransactions as T1 JOIN Adds as T2 ON T1.AddsID = T2.AddsID Where T1.CardID =" + cardID + "AND T1.Type = 1 Group By T1.CardID, T2.Title";
        cmd.CommandType = CommandType.Text;
        cmd.Connection = sqlConnection1;

        using(reader = cmd.ExecuteReader())
        {
            while (reader.Read())
            {
                quantity = reader["Quantity"].ToString();
            }
        } //reader gets disposed right here
    } //cmd gets disposed right here
    sqlConnection1.Close();
} //sqlConnection1 gets disposed right here

那么,我如何执行2个或更多查询并用同一个阅读器读取它们呢?当使用上述代码时,您可以,但不能同时使用两个。关闭第一个,然后继续读取第二个。您需要关闭并释放命令和读取器hanks@Patrick Hofman。我已经删除了@IanR.O'Brien的可能副本,其中一个是关于实体的,而这一个不是。不,建议这样做是危险的。在异常情况下,如果该行未执行,数据读取器将保持打开状态。“使用完DataReader对象后,应始终调用Close方法。如果命令包含输出参数或返回值,则在关闭DataReader之前,这些参数或返回值将不可用。请注意,当DataReader打开时,该连接由该DataReader独占使用。在原始DataReader关闭之前,您无法为连接执行任何命令,包括创建另一个DataReader。“(取自)另外……在出现异常的情况下,可以充分利用try-catch机制,然后在您的答案中解释。我不同意,给出半个可能有危险的答案并不是一个解决方案。@Levent您现在可以稍微解释一下为什么要使用所有东西,我知道您为确保一个连接而对新SqlConnection所做的一切一次打开一个,但是为什么要打开其他的呢?对于读卡器等,我不能只使用一个读卡器,即reader.Close();然后编写新的cmd.CommandText=“Select*from Users”;reader=cmd.ExecuteReader();等等..关闭读卡器->编写新的cmd文本->将结果添加到读卡器..不过还是要感谢您的回答!@Roxy'Pro基本上,所做的是在using语句中使用SqlConnection、SqlCommand和SqlDataReader。使用这些语句时,对象会在块完成后立即被处理。因此,您可以在以后重用它们,我将编辑这就像每次使用对象时都调用Dispose()(这也可以解决这个问题,但“使用”是正确的方法)@Nicorif的一个问题是,在使用语句时,我通常应该放置哪些对象,我的意思是,在块完成后,应该处理哪些类型的对象,比如,我如何知道为什么应该在使用语句时放置某些对象?@Nicorif的一个问题是,在使用语句时,我通常应该放置哪些对象,我的意思是应该放置哪些类型的对象在块完成后sposed,比如我怎么知道为什么要在using语句中使用某些内容?