SqlDataReader和SqlCommand

我有以下代码。

using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString)) { connection.Open(); SqlCommand select = new SqlCommand("SELECT RTRIM(LTRIM(PART_NO)) AS PART_NO, record FROM [RMAData].[dbo].[IMPORTING_ORDER_EDI] WHERE sessionID = '" + Session.SessionID + "'", connection); SqlDataReader reader = select.ExecuteReader(); if (reader.HasRows) { while (reader.Read()) { if (!currentPart.IsActive) { // this part is not active, set the active flag in sql to 0 SqlCommand update = new SqlCommand("UPDATE [RMAData].[dbo].[IMPORTING_ORDER_EDI] SET valid = 0, active = 0 WHERE record = " + reader["record"].ToString() + ";", connection); update.ExecuteNonQuery(); } else { ///blah } } reader.Close(); } } 

但这导致以下exception……

System.InvalidOperationException:已经有一个与此命令关联的打开的DataReader,必须先关闭它。

我需要读取返回的每一行,对数据进行一些validation并在必要时进行更新,然后继续下一条记录。 如果在循环阅读reader.Read()时无法使用SqlCommand ,我怎样才能实现这一点。 reader.Read()

另一种方法是不添加MultipleActiveResultSets = True – 这样做会有很小的性能损失 – 所以这样的事情:

 using (SqlConnection connection = new ...)) { connection.Open(); SqlCommand select = new SqlCommand(...); SqlDataReader reader = select.ExecuteReader(); var toInactivate = new List(); if (reader.HasRows) { while (reader.Read()) { if (!currentPart.IsActive) { toInactivate.Add(reader["record"].ToString()); } else { ///blah } } reader.Close(); } SqlCommand update = new SqlCommand("UPDATE ... SET valid = 0, active = 0 " + "WHERE record IN(" + string.Join(",", toInactivate) + ");", connection); update.ExecuteNonQuery(); } 

它具有在单个SQL语句中更新所有必需记录的优点。

当然,使用EF和Linq整个过程会非常整洁。

可以像修改连接字符串一样简单:

将MultipleActiveResultSets = True添加到连接字符串

您需要创建多个连接实例。
因为通常只能对连接执行一个命令
要么

按照@grantThomas的建议去做
或者您可以使用多个连接,如下所示

 using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString)) { connection.Open(); SqlCommand select = new SqlCommand("SELECT RTRIM(LTRIM(PART_NO)) AS PART_NO, record FROM [RMAData].[dbo].[IMPORTING_ORDER_EDI] WHERE sessionID = '" + Session.SessionID + "'", connection); SqlDataReader reader = select.ExecuteReader(); if (reader.HasRows) { while (reader.Read()) { if (!currentPart.IsActive) { // this part is not active, set the active flag in sql to 0 using (SqlConnection connection1 = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString)) { SqlCommand update = new SqlCommand("UPDATE [RMAData].[dbo].[IMPORTING_ORDER_EDI] SET valid = 0, active = 0 WHERE record = " + reader["record"].ToString() + ";", connection1); update.ExecuteNonQuery(); } } else { ///blah } } reader.Close(); } }