MySQL ADO.Net 嵌套数据读取器
MySQL ADO.Net Nested DataReaders
我想用一个 SQL 语句检索帐户列表,然后在 运行 更多 SQL 语句中循环遍历它们。当我尝试时,出现此错误:
Unhandled Exception: MySql.Data.MySqlClient.MySqlException: There is already an open DataReader associated with this Connection which must be closed first.
这是一个例子:
using (MySqlConnection connection = new MySqlConnection("host=..."))
{
connection.Open();
using (MySqlCommand cmdAccounts = connection.CreateCommand())
{
cmdAccounts.CommandText = "SELECT id, name FROM accounts";
using (MySqlDataReader accounts = cmdAccounts.ExecuteReader())
{
while (accounts.Read())
{
Console.WriteLine("Account {0}:", account.GetString("name"));
using (MySqlCommand cmdPictures = connection.CreateCommand())
{
cmdPictures.CommandText = "SELECT id, width, height FROM pictures WHERE account_id = @accountId";
cmdPictures.Parameters.AddWithValue("@accountId", accounts.GetInt32("id"));
using (MySqlDataReader pictures = cmdPictures.ExecuteReader())
{
while (pictures.Read())
{
Console.WriteLine("\tPicture #{0}: {1} x {2}", pictures.GetInt32("id"), picture2.GetInt32("width"), picture2.GetInt32("height"));
}
}
}
}
}
}
}
我是否必须使用 DataSet,或者在 MySQL 中是否可以仅使用 DataReader 来实现?
为什么不使用 SqlDataAdapter 填充数据表?
然后,对于数据表中的每一行,提取第二个 sql 命令并显示日期?
只是初学者的意见,尝试一下或查看更多答案
您可以使用 DataReader 执行此操作,但您需要为 reader 的两个级别使用单独的连接对象:
using (MySqlConnection connection = new MySqlConnection("host=..."))
using (MySqlCommand cmdAccounts = MySqlCommand("SELECT id, name FROM accounts" , connection))
{
connection.Open();
using (MySqlConnection connection2 = new MySqlConnection("host=..."))
using (MySqlCommand cmdPictures = new MySqlCommand("SELECT id, width, height FROM pictures WHERE account_id = @accountId", connection2))
using (MySqlDataReader accounts = cmdAccounts.ExecuteReader())
{
cmdPictures.Parameters.Add("@accountId", MySqlDbType.Int32);
connection2.Open()
while (accounts.Read())
{
Console.WriteLine("Account {0}:", account.getString("name"));
cmdPictures.Parameters["@accountId"].Value = accounts.GetInt32("id");
using (MySqlDataReader pictures = cmdPictures.ExecuteReader())
{
while (pictures.Read())
{
Console.WriteLine("\tPicture #{0}: {1} x {2}", pictures.GetInt32("id"), picture2.GetInt32("width"), picture2.GetInt32("height"));
}
}
}
}
}
但即使这样好多了,首先考虑问题的方式仍然是错误的。您确实想要 JOIN 数据库中的两个表:
string sql =
"SELECT a.id as AccountID, a.name, p.id as PictureID, p.width, p.height" +
" FROM accounts a" +
" INNER JOIN pictures p on p.account_id = a.id" +
" ORDER BY a.name, a.id";
using (var cn = new MySqlConnection("host=..."))
using (var cmd = new MySqlCommand(sql, cn))
{
cn.Open();
using (var rdr = cmd.ExecuteReader())
{
bool reading = rdr.Read();
while (reading)
{
int CurrentAccount = rdr.GetInt32("AccountId");
Console.WriteLine("Account {0}:", rdr.GetString("name"));
while (reading && CurrentAccount == rdr.GetInt32("AccountId"))
{
Console.WriteLine("\tPicture #{0}: {1} x {2}",
rdr.GetInt32("PictureId"), rdr.GetInt32("width"), rdr.GetInt32("height"));
reading = rdr.Read();
}
}
}
}
我想用一个 SQL 语句检索帐户列表,然后在 运行 更多 SQL 语句中循环遍历它们。当我尝试时,出现此错误:
Unhandled Exception: MySql.Data.MySqlClient.MySqlException: There is already an open DataReader associated with this Connection which must be closed first.
这是一个例子:
using (MySqlConnection connection = new MySqlConnection("host=..."))
{
connection.Open();
using (MySqlCommand cmdAccounts = connection.CreateCommand())
{
cmdAccounts.CommandText = "SELECT id, name FROM accounts";
using (MySqlDataReader accounts = cmdAccounts.ExecuteReader())
{
while (accounts.Read())
{
Console.WriteLine("Account {0}:", account.GetString("name"));
using (MySqlCommand cmdPictures = connection.CreateCommand())
{
cmdPictures.CommandText = "SELECT id, width, height FROM pictures WHERE account_id = @accountId";
cmdPictures.Parameters.AddWithValue("@accountId", accounts.GetInt32("id"));
using (MySqlDataReader pictures = cmdPictures.ExecuteReader())
{
while (pictures.Read())
{
Console.WriteLine("\tPicture #{0}: {1} x {2}", pictures.GetInt32("id"), picture2.GetInt32("width"), picture2.GetInt32("height"));
}
}
}
}
}
}
}
我是否必须使用 DataSet,或者在 MySQL 中是否可以仅使用 DataReader 来实现?
为什么不使用 SqlDataAdapter 填充数据表? 然后,对于数据表中的每一行,提取第二个 sql 命令并显示日期? 只是初学者的意见,尝试一下或查看更多答案
您可以使用 DataReader 执行此操作,但您需要为 reader 的两个级别使用单独的连接对象:
using (MySqlConnection connection = new MySqlConnection("host=..."))
using (MySqlCommand cmdAccounts = MySqlCommand("SELECT id, name FROM accounts" , connection))
{
connection.Open();
using (MySqlConnection connection2 = new MySqlConnection("host=..."))
using (MySqlCommand cmdPictures = new MySqlCommand("SELECT id, width, height FROM pictures WHERE account_id = @accountId", connection2))
using (MySqlDataReader accounts = cmdAccounts.ExecuteReader())
{
cmdPictures.Parameters.Add("@accountId", MySqlDbType.Int32);
connection2.Open()
while (accounts.Read())
{
Console.WriteLine("Account {0}:", account.getString("name"));
cmdPictures.Parameters["@accountId"].Value = accounts.GetInt32("id");
using (MySqlDataReader pictures = cmdPictures.ExecuteReader())
{
while (pictures.Read())
{
Console.WriteLine("\tPicture #{0}: {1} x {2}", pictures.GetInt32("id"), picture2.GetInt32("width"), picture2.GetInt32("height"));
}
}
}
}
}
但即使这样好多了,首先考虑问题的方式仍然是错误的。您确实想要 JOIN 数据库中的两个表:
string sql =
"SELECT a.id as AccountID, a.name, p.id as PictureID, p.width, p.height" +
" FROM accounts a" +
" INNER JOIN pictures p on p.account_id = a.id" +
" ORDER BY a.name, a.id";
using (var cn = new MySqlConnection("host=..."))
using (var cmd = new MySqlCommand(sql, cn))
{
cn.Open();
using (var rdr = cmd.ExecuteReader())
{
bool reading = rdr.Read();
while (reading)
{
int CurrentAccount = rdr.GetInt32("AccountId");
Console.WriteLine("Account {0}:", rdr.GetString("name"));
while (reading && CurrentAccount == rdr.GetInt32("AccountId"))
{
Console.WriteLine("\tPicture #{0}: {1} x {2}",
rdr.GetInt32("PictureId"), rdr.GetInt32("width"), rdr.GetInt32("height"));
reading = rdr.Read();
}
}
}
}