我需要使用 SqlDataReader 处理列表中的数据。为此,我编写了一个 for 循环,其中将提供查询数据并进入 SqlDataReader。但是在第一次迭代之后,循环中断了。显示错误,需要关闭 SqlDataReader。
List<string> days = new List<string>() { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" };
SqlConnection cnn = new SqlConnection(@"Con");
cnn.Open();
SqlCommand cmd = cnn.CreateCommand();
List<string> data = new List<string>();
for (int i = 0; i < days.Count;i++)
{
cmd.CommandText = $@"select * from Table where Day = '{days[i]}'";
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
data.Add(reader[0].ToString());
}
}
在这里,例如,我使用“天”列表,但在程序本身中,该列表是从查询中获得的,因此它可以更大。这是发生错误的地方。我试图关闭 SqlDataReader,但问题是它无法重新打开。无论如何,我需要以某种方式在循环中从 SqlDataReader 获取数据。
是的,你应该
Dispose
实现IDisposable
的实例:一个快速的补丁,但是不是最好的解决方案是添加using
:
...
for (int i = 0; i < days.Count; i++) {
cmd.CommandText = $@"select * from Table where Day = '{days[i]}'";
// using to Dispose reader
using (SqlDataReader reader = cmd.ExecuteReader()) {
while (reader.Read())
data.Add(reader[0].ToString());
}
}
更好的方法是只调用一次查询(SQL 很昂贵):
var data = new List<string>();
var days = new List<string>() {
"Monday", "Tuesday", "Wednesday", "Thursday", "Friday"
};
using SqlConnection cnn = new SqlConnection(@"Con");
cnn.Open();
//TODO: change * into the only field(s) you want to fetch
// Since days are list of constants I haven't created bind variables:
// - No sql injection
// - Constants are specific and in specific order (workdays) so
// I want the query be specific and not mixed with in (:param1, ... :paramN)
// for arbitrary days
string sql =
$@"select *
from Table
where day in ({string.Join(", ", days.Select(day => $"'{day}'"))})";
using SqlCommand cmd = cnn.CreateCommand(sql, cnn);
using SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read()) {
data.Add(Convert.ToString(reader[0]));
}
你可以使用 while 循环
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command = new SqlCommand(queryString, connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
try
{
while (reader.Read())
{
Console.WriteLine(String.Format("{0}, {1}",
reader["Column1"], reader["Column2"]));
}
}
finally
{
// Always call Close when done reading.
reader.Close();
}
}
SqlDataReader 在while 循环中用于从数据库中读取数据。循环继续,直到没有更多数据可读