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(); } }