C# 在C中处理SqlCommand的概念

C# 在C中处理SqlCommand的概念,c#,sql,sqldatareader,sqlconnection,C#,Sql,Sqldatareader,Sqlconnection,我正在尝试从数据库中选择一个用户列表,并根据条件isSent==false向每个用户发送电子邮件。向他们发送电子邮件后,此false的值应更新为true。下面的代码是我从数据库中检索用户列表并向每个用户调用sendmail方法的方法 myConnection.Open(); //******* try { SqlDataReader myReader = null;

我正在尝试从数据库中选择一个用户列表,并根据条件isSent==false向每个用户发送电子邮件。向他们发送电子邮件后,此false的值应更新为true。下面的代码是我从数据库中检索用户列表并向每个用户调用sendmail方法的方法

           myConnection.Open();
            //*******
            try
            {
                SqlDataReader myReader = null;
                string sql = "SELECT * FROM testTable where isSent = false";
                SqlCommand myCommand = new SqlCommand(sql, myConnection);
                myReader = myCommand.ExecuteReader();

                while (myReader.Read())
                {
                    sendEmail(myReader["emailAdd"].ToString(), 
                              myReader["UserID"].ToString());
                }
第二部分:

public static void sendEmail(string emailAdd,string userID){
    .
    .
    .
    try
    {
        smtpClient.Send(mail);
        try
            {
                string sql = "UPDATE testTable SET isSent = 1 WHERE  UserID = " + userID;
                SqlCommand myCommand = new SqlCommand(sql, myConnection);
                int rows = myCommand.ExecuteNonQuery();
                .
                .
                .
            }
    }
}
我面临的问题是,因为从main方法开始,我已经有了SqlDataReader被保持读取,所以我现在无法更新。有我的工作吗?我得到的错误消息如下:

There is already an open DataReader associated with this Command which must be closed first.
我面临的问题是,因为从main方法开始,我已经有了SqlDataReader被保持读取,所以我现在无法更新。有我的工作吗

这只是一个问题,因为您正在共享连接myConnection。不要那样做。每次要执行数据库操作时,都要创建一个新的SqlConnection,并让连接池基础结构处理,以提高效率。另外,对数据库相关资源使用using语句:

using (var connection = new SqlConnection(...))
{
    using (var command = new SqlCommand(...))
    {
        using (var reader = command.ExecuteReader(...))
        {
            ...
        }
    }
}
我面临的问题是,因为从main方法开始,我已经有了SqlDataReader被保持读取,所以我现在无法更新。有我的工作吗

这只是一个问题,因为您正在共享连接myConnection。不要那样做。每次要执行数据库操作时,都要创建一个新的SqlConnection,并让连接池基础结构处理,以提高效率。另外,对数据库相关资源使用using语句:

using (var connection = new SqlConnection(...))
{
    using (var command = new SqlCommand(...))
    {
        using (var reader = command.ExecuteReader(...))
        {
            ...
        }
    }
}

作为另一种选择。您可以将其添加到数据库的连接字符串中

MultipleActiveResultSets=True


有一点性能下降。而且它在较旧的SQL Server中不受支持。我认为2005年以前是另一种选择。您可以将其添加到数据库的连接字符串中

MultipleActiveResultSets=True

有一点性能下降。而且它在较旧的SQL Server中不受支持。我想在2005年之前试试这个代码`

 public static void sendEmail(string emailAdd,string userID){
  try
    {
        SqlConnection con = new SqlConnection(@"");
        con.Open();

        MailMessage mail = new MailMessage("example@gmail.com", emailAdd);
        SmtpClient smtpClient = new SmtpClient();
        NetworkCredential nc = new NetworkCredential("example@gmail.com", "test");

        smtpClient.Port = 587;
        smtpClient.Host = "smtp.gmail.com";
        smtpClient.EnableSsl = true;
        smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
        smtpClient.UseDefaultCredentials = false;
       // smtpClient.Host = "smtp.google.com";
        mail.Subject = "this is a test email.";
        mail.Body = "this is my test email body";
        smtpClient.Credentials = nc;
        smtpClient.Send(mail);

        using (SqlCommand cmd = con.CreateCommand())
        {
            string sql = "UPDATE TestTable SET IsSent = 'true' WHERE  UserID = " + userID;
            SqlCommand myCommand = new SqlCommand(sql, con);
            int rows = myCommand.ExecuteNonQuery();
        }
    }
    catch(Exception e)
    {
        string message = e.Message;
    }`
 }
请尝试此代码`

 public static void sendEmail(string emailAdd,string userID){
  try
    {
        SqlConnection con = new SqlConnection(@"");
        con.Open();

        MailMessage mail = new MailMessage("example@gmail.com", emailAdd);
        SmtpClient smtpClient = new SmtpClient();
        NetworkCredential nc = new NetworkCredential("example@gmail.com", "test");

        smtpClient.Port = 587;
        smtpClient.Host = "smtp.gmail.com";
        smtpClient.EnableSsl = true;
        smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
        smtpClient.UseDefaultCredentials = false;
       // smtpClient.Host = "smtp.google.com";
        mail.Subject = "this is a test email.";
        mail.Body = "this is my test email body";
        smtpClient.Credentials = nc;
        smtpClient.Send(mail);

        using (SqlCommand cmd = con.CreateCommand())
        {
            string sql = "UPDATE TestTable SET IsSent = 'true' WHERE  UserID = " + userID;
            SqlCommand myCommand = new SqlCommand(sql, con);
            int rows = myCommand.ExecuteNonQuery();
        }
    }
    catch(Exception e)
    {
        string message = e.Message;
    }`
 }

如果我没有正确理解它,我很抱歉,因为它仍然在抱怨相同的错误。我在我的主方法中使用了你的代码片段,在我的sendMail方法中使用了另一组代码片段,它应该工作正常吗?@IsaacLem:你没有告诉我们你在说什么错误,这使得很难说出错误。但是,如果您在每段代码中创建一个单独的连接,那么从这个角度来看应该没问题。在更新查询所处理的数据时,从查询读取的事务性可能存在问题,但这是另一回事。我已编辑了我的问题,其中包括错误消息。两种方式都会给我相同的错误信息。想象一下,第一个查询返回了3行A、B和C。我现在正试图更新A行的一列。这会有什么问题吗?当您有两个完全独立的连接、命令和读卡器时,不应该出现异常。你确定你的新代码和我的一样,声明新的变量等等?我的错。我倾向于创建另一个同名变量,让它覆盖旧变量,而旧变量显然会给出错误。非常感谢你!如果我没有正确理解它,我很抱歉,因为它仍然在抱怨相同的错误。我在我的主方法中使用了你的代码片段,在我的sendMail方法中使用了另一组代码片段,它应该工作正常吗?@IsaacLem:你没有告诉我们你在说什么错误,这使得很难说出错误。但是,如果您在每段代码中创建一个单独的连接,那么从这个角度来看应该没问题。在更新查询所处理的数据时,从查询读取的事务性可能存在问题,但这是另一回事。我已编辑了我的问题,其中包括错误消息。两种方式都会给我相同的错误信息。想象一下,第一个查询返回了3行A、B和C。我现在正试图更新A行的一列。这会有什么问题吗?当您有两个完全独立的连接、命令和读卡器时,不应该出现异常。你确定你的新代码和我的一样,声明新的变量等等?我的错。我倾向于创建另一个同名变量,让它覆盖旧变量,而旧变量显然会给出错误。非常感谢你!我使用的是如下所示的sqlConnection:静态sqlConnection myConnection=new SqlConnectionuser id=xxx;+密码=xxx;服务器=xxx;+可信连接=是;+数据库=xxx;+连接超时=30;您的方法对此不可行?根据SQL Server的版本,您只需将MultipleActiveResultSets=true添加到字符串,即新的SqlConnectionuser id=xxx;+密码=xxx;服务器=xxx;+可信连接=是;+数据库=xxx;+连接超时=
30;multipleactiveresultsets=true;我使用的是SSMS 2008,它给了我一个sqlinitialize例外我使用的是sqlConnection,如下所示:静态sqlConnection myConnection=new SqlConnectionuser id=xxx;+密码=xxx;服务器=xxx;+可信连接=是;+数据库=xxx;+连接超时=30;您的方法对此不可行?根据SQL Server的版本,您只需将MultipleActiveResultSets=true添加到字符串,即新的SqlConnectionuser id=xxx;+密码=xxx;服务器=xxx;+可信连接=是;+数据库=xxx;+连接超时=30;multipleactiveresultsets=true;我使用的是SSMS2008,它给了我一个sqlinitialize异常