C# 错误:已存在与此命令关联的打开的DataReader,必须先关闭它

C# 错误:已存在与此命令关联的打开的DataReader,必须先关闭它,c#,sql,sql-server,C#,Sql,Sql Server,我正在创建一个登记表,我必须检查电子邮件是否有效,是否已经在我的数据库中使用。我想出了一个方法,但我的代码中有错误。如果它显示“有问题”,在我尝试使用新的电子邮件地址后,我在DataReader上出现错误,如果我直接使用新的电子邮件地址,它在ExecuteOnQuery上显示错误。有什么想法吗 我验证电子邮件地址的方法可以单独工作。谢谢 public bool IsValidEmail(string emailadress) { try {

我正在创建一个登记表,我必须检查电子邮件是否有效,是否已经在我的数据库中使用。我想出了一个方法,但我的代码中有错误。如果它显示“有问题”,在我尝试使用新的电子邮件地址后,我在DataReader上出现错误,如果我直接使用新的电子邮件地址,它在
ExecuteOnQuery
上显示错误。有什么想法吗

我验证电子邮件地址的方法可以单独工作。谢谢

    public bool IsValidEmail(string emailadress)
    {
        try
        {
            MailAddress m = new MailAddress(emailadress);
            return true;
        }
        catch
        {
            return false;
        }
    }

    public bool good(string emailadress)
    {
        SqlCommand cmd = new SqlCommand("SELECT Email FROM Clients", con);
        SqlDataReader dr = cmd.ExecuteReader();//error is here

        while (dr.Read())
        {
            if (dr[0].ToString() == textBox6.Text)
            {
                return false;
            }
        }

        return true;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        if (IsValidEmail(textBox6.Text) && good(textBox6.Text))
        {
            SqlCommand cmd1 = new SqlCommand("insert into Clienti(Name , Prename , Adress , Pass , Email ) values (@name , @prename ,@adress , @pass , @email)", con);
            cmd1.Parameters.AddWithValue("name", textBox1.Text);
            cmd1.Parameters.AddWithValue("prename", textBox2.Text);
            cmd1.Parameters.AddWithValue("adress", textBox3.Text);
            cmd1.Parameters.AddWithValue("pass", textBox4.Text);
            cmd1.Parameters.AddWithValue("email", textBox6.Text);

            cmd1.ExecuteNonQuery();    // error happens here

            cmd1.Dispose();
            MessageBox.Show("success");
        }
        else
            MessageBox.Show("something went wrong");
    }

在从
good
函数返回值之前,请尝试关闭读卡器。如下图所示:

public bool good(字符串电子邮件地址)
{
SqlCommand cmd=newsqlcommand(“从客户端选择电子邮件”,con);
SqlDataReader dr=cmd.ExecuteReader();//此处有错误
while(dr.Read())
{
if(dr[0].ToString()==textBox6.Text)
{
Close博士();
返回false;
}
}
Close博士();
返回true;
}

SqlDataReader在使用后应该关闭,否则它会保持连接锁定,在关闭连接之前您无法使用该连接。
但是,如果您已经注册了电子邮件地址,则不需要SqlDataReader来发现

public bool good(string emailadress)
{
    string query = @"IF EXISTS(SELECT 1 FROM Clients WHERE Email = @email) 
                     SELECT 1 ELSE SELECT 0";
    SqlCommand cmd = new SqlCommand(query, con);
    cmd.Parameters.Add("@email", SqlDbType.NVarChar).Value = emailadress;
    int result = (int)cmd.ExecuteScalar();
    return (result == 1);
}
请记住,像SqlCommand、SqlDataReader这样的一次性对象,但最重要的是,SqlConnection应该在您需要它们的时候创建,并立即释放以释放有价值的资源。
上面的代码以及现场创建的连接将是:

public bool good(string emailadress)
{

    string query = @"IF EXISTS(SELECT 1 FROM Clients WHERE Email = @email) 
                     SELECT 1 ELSE SELECT 0";
    using(SqlConnection con = new SqlConnection(....here put your connection string...))
    using(SqlCommand cmd = new SqlCommand(query, con))
    {
        con.Open();
        cmd.Parameters.Add("@email", SqlDbType.NVarChar).Value = emailadress;
        int result = (int)cmd.ExecuteScalar();
        return (result == 1);
   }
}

仍然抛出一个错误。在我收到“出错”消息并且我正在更改DataReader中出现错误的内容之后,为什么要检索整个Clients表以检查电子邮件地址是否匹配?这类检查有Where SQL子句。为什么要保留一个全局连接对象?在需要时创建连接,然后进行处理