我有以下代码(此处具有用于可读性的伪值),其中第一个连接返回大量数据(数千行)。 SqlDataReader通过reader.Read()
逐一读取它们,然后打开一个新连接以用新值更新每一行:
using (SqlConnection conn = new SqlConnection(connString))
using (SqlCommand cmd = new SqlCommand("sp1", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@param1", param1);
cmd.Connection.Open();
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
try
{
string hash= utils.SHA256.Hashing((string)reader["firstRow"], saltValue);
using (SqlConnection conn2 = new SqlConnection(connString))
using (SqlCommand cmd2 = new SqlCommand("sp2", conn2))
{
cmd2.CommandType = CommandType.StoredProcedure;
cmd2.Parameters.AddWithValue("@param1", param1);
cmd2.Parameters.AddWithValue("@param2", param2);
cmd2.Connection.Open();
cmd2.ExecuteNonQuery();
}
}
catch (SqlException ex)
{
//something
}
}
}
}
但是它抛出一个错误:
[InvalidOperationException: Invalid attempt to call Read when reader is closed.]
System.Data.SqlClient.SqlDataReader.ReadInternal(Boolean setTimeout) +640
System.Data.SqlClient.SqlDataReader.Read() +9
在开发环境中,它可以正常工作,但是这里只有几百行。它会立即引发错误,因此它看起来不像是某种超时,但是,嘿-我不知道...
最佳答案
不知道为什么会这样,但是在迭代到同一数据库的实时连接时执行查询确实是一个坏主意。请记住,只要您使用DataReader迭代记录,连接就处于活动状态。
更糟糕的是,快速连续打开然后关闭连接数千次。仅此一项就可以使任何数据库瘫痪。
更改逻辑,将所需的值存储在局部变量(结构无关紧要)中,然后仅使用一个连接来执行所需的所有存储过程。
例如:
using (SqlConnection conn = new SqlConnection(connString))
{
conn.Open();
List<string[]> values = new List<string[]>();
using (SqlCommand cmd = new SqlCommand("sp1", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@param1", param1);
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
try
{
string hash= utils.SHA256.Hashing((string)reader["firstRow"], saltValue);
string anotherValue = (string)reader["secondRow"];
values.Add(new string[] { hash, anotherValue });
}
catch (SqlException ex)
{
//something
}
}
reader.Close();
}
}
if (values.Count > 0)
{
using (SqlCommand cmd2 = new SqlCommand("sp2", conn))
{
cmd2.CommandType = CommandType.StoredProcedure;
cmd2.Parameters.AddWithValue("@param1", null);
cmd2.Parameters.AddWithValue("@param2", null);
values.ForEach(items =>
{
cmd2.Parameters["@param1"].Value = items[0];
cmd2.Parameters["@param2"].Value = items[1];
cmd2.ExecuteNonQuery();
});
}
}
conn.Close();
}
一个连接,一个命令即可执行所有存储过程。真的不需要更多。
关于c# - 得到“关闭阅读器后,无效的尝试调用Read的尝试”,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13455963/