简体   繁体   English

与C#中此命令错误关联的打开的数据读取器

[英]An open datareader associated with this command error in C#

I want to build a simple loop to check incoming data from SQL server, compare it to a textfield, and execute non query if there are no duplicates. 我想构建一个简单的循环来检查来自SQL Server的传入数据,将其与文本字段进行比较,并在没有重复的情况下执行非查询。

I wrote this code: 我写了这段代码:

try
{
    bool exists = false;
    conn = new SqlConnection(DBConnectionString);

    SqlCommand check_user = new SqlCommand("SELECT usrEmail FROM tblUsers", conn);
    SqlCommand add_user = new SqlCommand("INSERT INTO tblUsers (usrEmail, usrPassword, usrRealname, usrIsowner) VALUES (@email, @pass, @name, @owner)", conn);
    // (I have removed all the paramaters from this code as they are working and irrelevant)
    conn.Open();

    SqlDataReader check = check_user.ExecuteReader();

    while (check.Read())
    {
        if (Convert.ToString(check[0]) == UserEmail.Text)
        {
            MessageBox.Show("The email you entered already exists in the system.");
            exists = true;
            break;
        }
    }

    if (exists == false)
    {
        add_user.ExecuteNonQuery();
    }
    else
    {
        return;
    }
}
catch (Exception ex)
{
    MessageBox.Show("There was a problem uploading data to the database. Please review the seller's details and try again. " + ex.Message);
    return;
}
finally
{
    conn.Close();
}

I used breakpoints and saw that the code runs the while loop fine, but when it reaches the ExecuteNonQuery command, it returns an error message: 我使用断点,发现代码可以正常运行while循环,但是当它到达ExecuteNonQuery命令时,它返回一条错误消息:

there is already an open datareader associated with this command which must be closed first 已经有一个与此命令相关的打开的数据读取器,必须首先关闭

I tried to use a check.Close(); 我试图使用check.Close(); command, but when I do, it suddenly gets stuck with the duplicate email error message for reasons passing understanding. 命令,但是当我这样做时,由于通过理解的原因,它突然卡在重复的电子邮件错误消息中。 Additionally, there was a fix I tried in which the data actually WAS sent to the database (I saw it in SQL Server Management Studio), but still gave an error message... That was even stranger, since the nonquery command is the LAST in this function. 另外,我尝试了一个修复程序,其中数据实际上已发送到数据库(我在SQL Server Management Studio中看到了),但是仍然给出了错误消息...甚至更奇怪,因为nonquery命令是LAST在此功能。 If it worked, why did it go to the catch? 如果奏效了,为什么要去抓呢?

I have searched the site for answers, but the most common answers are MARS (I have no idea what that is) or a dataset, which I do not want to use in this case. 我已经在站点上搜索了答案,但是最常见的答案是MARS(我不知道那是什么)或数据集,在这种情况下,我不想使用它们。

Is there a simple solution here? 这里有一个简单的解决方案吗? Did I miss something in the code? 我错过了代码中的某些内容吗?

The simples way out would be: 简单的解决方法是:

using(SqlDataReader check = check_user.ExecuteReader())
{
    while (check.Read())
    {
        if (Convert.ToString(check[0]) == UserEmail.Text)
        {
            MessageBox.Show("The email you entered already exists in the system.");
            exists = true;
            break;
        }
    }
}

That said, there are some serious problems with this code. 也就是说,此代码存在一些严重的问题。

First of all, you don't really want to read all users just to check that an email address is already taken. 首先,您并不是只想阅读所有用户以检查是否已使用电子邮件地址。 select count(*) from tblUsers where usrEmail = @email is fine... select count(*) from tblUsers where usrEmail = @email很好...

...or not, because there's a possibility of a race condition. ...或没有,因为有可能发生比赛。 What you should do is add a unique constraint on a usrEmail column and just insert into tblUsers , catching violations. 您应该做的是在usrEmail列上添加唯一约束,然后insert into tblUsers ,以捕获违规情况。 Or you can use merge if you feel like it. 或者,您可以根据需要使用merge

Next, you don't really want to have your data access code all over the place. 接下来,您真的不需要到处都有数据访问代码。 Factor it out into separate classes/methods at least. 至少将其分解为单独的类/方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM