C# 中已经有一个打开的 Datareader 关联

Posted

技术标签:

【中文标题】C# 中已经有一个打开的 Datareader 关联【英文标题】:There is already an open Datareader associated in C# 【发布时间】:2013-10-18 15:21:55 【问题描述】:

我似乎找不到这个错误背后的原因。有人可以查看我的代码吗?

private void button2_Click_1(object sender, EventArgs e)

    con.Open();

    string check
        = "Select block, section, size from interment_location where block='"
          + textBox12.Text
          + "' and section='"
          + textBox13.Text
          + "' and size='"
          + textBox14.Text
          + "'";

    SqlCommand cmd1 = new SqlCommand(check, con);
    SqlDataReader rdr;
    rdr = cmd1.ExecuteReader();

    try
    
        if (textBox1.Text == ""
            || textBox2.Text == ""
            || textBox3.Text == ""
            || textBox4.Text == ""
            || textBox7.Text == ""
            || textBox8.Text == ""
            || textBox9.Text == ""
            || textBox10.Text == ""
            || dateTimePicker1.Value.ToString("yyyyMMdd HH:mm:ss") == ""
            || dateTimePicker2.Value.ToString("yyyyMMdd HH:mm:ss") == ""
            || textBox11.Text == ""
            || dateTimePicker3.Value.ToString("yyyyMMdd HH:mm:ss") == ""
            || textBox12.Text == ""
            || textBox13.Text == ""
            || textBox14.Text == "")
        
            MessageBox.Show(
                "Please input a value!",
                "Error",
                MessageBoxButtons.OK,
                MessageBoxIcon.Exclamation);
        
        else if (rdr.HasRows == true)
        
            MessageBox.Show("Interment Location is already reserved.");
            textBox12.Clear();
            textBox13.Clear();
            textBox14.Clear();
            textBox12.Focus();
        
        else if (MessageBox.Show(
            "Are you sure you want to reserve this record?",
            "Reserve",
            MessageBoxButtons.YesNo,
            MessageBoxIcon.Question) == DialogResult.Yes)
        
            SqlCommand cmd4 = new SqlCommand(
                "insert into owner_info(ownerf_name, ownerm_name,"
                    + " ownerl_name, home_address, tel_no, office)"
                    + " values('"
                    + textBox1.Text
                    + "', '"
                    + textBox2.Text
                    + "', '"
                    + textBox3.Text
                    + "', '"
                    + textBox4.Text
                    + "', '"
                    + textBox7.Text
                    + "', '"
                    + textBox8.Text
                    + "')",
                con);

            cmd.ExecuteNonQuery();

            SqlCommand cmd5 = new SqlCommand(
                "insert into deceased_info(deceased_id, name_of_deceased, "
                    + "address, do_birth, do_death, place_of_death, "
                    + "date_of_interment, COD_id, place_of_vigil_id, "
                    + "service_id, owner_id) values('"
                    + ownerid
                    + "','"
                    + textBox9.Text
                    + "', '"
                    + textBox10.Text
                    + "', '"
                    + dateTimePicker1.Value.ToString("yyyyMMdd HH:mm:ss")
                    + "', '"
                    + dateTimePicker2.Value.ToString("yyyyMMdd HH:mm:ss")
                    + "', '"
                    + textBox11.Text
                    + "', '"
                    + dateTimePicker3.Value.ToString("yyyyMMdd HH:mm:ss")
                    + "', '"
                    + ownerid
                    + "', '"
                    + ownerid
                    + "', '"
                    + ownerid
                    + "', '"
                    + ownerid
                    + "')",
                con); 

            cmd.ExecuteNonQuery();

            SqlCommand cmd6 = new SqlCommand(
                "insert into interment_location(lot_no, block, section, "
                    + "size, garden_id) values('"
                    + ownerid
                    + "','"
                    + textBox12.Text
                    + "', '"
                    + textBox13.Text
                    + "', '"
                    + textBox14.Text
                    + "', '"
                    + ownerid
                    + "')",
                con);

            cmd.ExecuteNonQuery();

            MessageBox.Show(
                "Your reservation has been made!",
                "Reserve",
                MessageBoxButtons.OK,
                MessageBoxIcon.Information); 
        
    
    catch (Exception x)
    
        MessageBox.Show(x.Message);
    

    con.Close();    

这是我之后编辑的唯一代码。

【问题讨论】:

***.com/questions/2519379/…请参考链接 我已经关闭了该方法。我是不是放错地方了? 你正在关闭连接而不是阅读器! 请看下面的答案:***.com/a/4472414/2424 它展示了使用连接、命令、读取器和参数对象的最佳实践方式。就你目前的代码而言,它可能会泄漏内存、sql 连接并允许 sql 注入攻击。 Exception: There is already an open DataReader associated with this Connection which must be closed first的可能重复 【参考方案1】:

试试下面的代码,看看是否适合你。

 else if (rdr.HasRows == true)
    
        MessageBox.Show("Interment Location is already reserved.");
        textBox12.Clear();
        textBox13.Clear();
        textBox14.Clear();
        textBox12.Focus();
    
rdr.close() // close your reader here!

【讨论】:

【参考方案2】:
private void button2_Click_1(object sender, EventArgs e)

  con.Open();

    string check
    = "Select block, section, size from interment_location where block='"
      + textBox12.Text
      + "' and section='"
      + textBox13.Text
      + "' and size='"
      + textBox14.Text
      + "'";

SqlCommand cmd1 = new SqlCommand(check, con);
SqlDataReader rdr;
rdr = cmd1.ExecuteReader();

try

    if (textBox1.Text == ""
        || textBox2.Text == ""
        || textBox3.Text == ""
        || textBox4.Text == ""
        || textBox7.Text == ""
        || textBox8.Text == ""
        || textBox9.Text == ""
        || textBox10.Text == ""
        || dateTimePicker1.Value.ToString("yyyyMMdd HH:mm:ss") == ""
        || dateTimePicker2.Value.ToString("yyyyMMdd HH:mm:ss") == ""
        || textBox11.Text == ""
        || dateTimePicker3.Value.ToString("yyyyMMdd HH:mm:ss") == ""
        || textBox12.Text == ""
        || textBox13.Text == ""
        || textBox14.Text == "")
    
        MessageBox.Show(
            "Please input a value!",
            "Error",
            MessageBoxButtons.OK,
            MessageBoxIcon.Exclamation);
    
    else if (rdr.HasRows == true)
    
        MessageBox.Show("Interment Location is already reserved.");
        textBox12.Clear();
        textBox13.Clear();
        textBox14.Clear();
        textBox12.Focus();
    
    else if (MessageBox.Show(
        "Are you sure you want to reserve this record?",
        "Reserve",
        MessageBoxButtons.YesNo,
        MessageBoxIcon.Question) == DialogResult.Yes)
    
        if (!rdr.IsClosed) 
                rdr.Close(); //close the data reader
        SqlCommand cmd4 = new SqlCommand(
            "insert into owner_info(ownerf_name, ownerm_name,"
                + " ownerl_name, home_address, tel_no, office)"
                + " values('"
                + textBox1.Text
                + "', '"
                + textBox2.Text
                + "', '"
                + textBox3.Text
                + "', '"
                + textBox4.Text
                + "', '"
                + textBox7.Text
                + "', '"
                + textBox8.Text
                + "')",
            con);

        cmd.ExecuteNonQuery();

        SqlCommand cmd5 = new SqlCommand(
            "insert into deceased_info(deceased_id, name_of_deceased, "
                + "address, do_birth, do_death, place_of_death, "
                + "date_of_interment, COD_id, place_of_vigil_id, "
                + "service_id, owner_id) values('"
                + ownerid
                + "','"
                + textBox9.Text
                + "', '"
                + textBox10.Text
                + "', '"
                + dateTimePicker1.Value.ToString("yyyyMMdd HH:mm:ss")
                + "', '"
                + dateTimePicker2.Value.ToString("yyyyMMdd HH:mm:ss")
                + "', '"
                + textBox11.Text
                + "', '"
                + dateTimePicker3.Value.ToString("yyyyMMdd HH:mm:ss")
                + "', '"
                + ownerid
                + "', '"
                + ownerid
                + "', '"
                + ownerid
                + "', '"
                + ownerid
                + "')",
            con); 

        cmd.ExecuteNonQuery();

        SqlCommand cmd6 = new SqlCommand(
            "insert into interment_location(lot_no, block, section, "
                + "size, garden_id) values('"
                + ownerid
                + "','"
                + textBox12.Text
                + "', '"
                + textBox13.Text
                + "', '"
                + textBox14.Text
                + "', '"
                + ownerid
                + "')",
            con);

        cmd.ExecuteNonQuery();

        MessageBox.Show(
            "Your reservation has been made!",
            "Reserve",
            MessageBoxButtons.OK,
            MessageBoxIcon.Information); 
    

catch (Exception x)

    MessageBox.Show(x.Message);

if (!rdr.IsClosed)
    rdr.Close(); //close the datareader if it is not closed already
con.Close();    

【讨论】:

我已经尝试过了,但我不断收到“对象引用未设置为对象的实例。 好的,刚刚解决了您的错误“已经有一个打开的 Datareader 关联.....”首先您将连接分配给打开 DataReader 的命令,然后您使用相同的连接用于插入记录。解决方法: 1. 插入记录前通过dr.Close()关闭datareader。 2.更改插入命令的连接对象。

以上是关于C# 中已经有一个打开的 Datareader 关联的主要内容,如果未能解决你的问题,请参考以下文章

已经有一个打开的 DataReader 与此命令关联,必须先关闭

错误:已经有一个与此命令关联的打开DataReader,必须先关闭它。多个用户

已经有一个打开的 DataReader 与此命令关联,必须先关闭

entityframework 已经有一个与此命令关联的打开的 DataReader 必须先关闭

实体框架:已经有一个打开的 DataReader 与此命令关联

已经有一个打开的 DataReader 与此命令关联,必须先关闭