如何为每个读取 ID 执行另一个 MySqlDataReader?

How to execute another MySqlDataReader for each read ID?

我正在尝试从我的数据库中获取一些 data,每个 data 可能有一些 attributes,所以我的逻辑是在获取所有 data 因此,在执行 MySqlDataReader 时,我打算对每个 id 数据执行查询,我得到的是 attributes.

但是我 运行 出错了:'There is already an open DataReader associated with this Connection' 所以我猜我不能 运行 同时 MySqlDataReader 所以在这一点上,这将是每个 data?

获得 attributes 的最佳方法

我是否应该在将每个 Plu 元素添加到列表后循环处理它们,还是有更好的解决方案?

这是我获取 data(Plu 对象)

的函数
        public IEnumerable<Plu> GetPlu(string piva, int menu)
        {
            string connectionString = $"CONSTR";
            using var connection = new MySqlConnection(connectionString);
            connection.Open();

            var sql = @"QUERY";

            using var cmd = new MySqlCommand(sql, connection);
            cmd.Parameters.AddWithValue("@menu", menu);
            cmd.Prepare();

            using MySqlDataReader reader = cmd.ExecuteReader();

            List<Plu> plu = new List<Plu>();

            while (reader.Read())
            {
                plu.Add(new Plu(
                    (int)reader["ID_PLUREP"],
                    (string)reader["CODICE_PRP"],
                    (string)reader["ESTESA_DES"],
                    (string)reader["DESCR_DES"], (float)reader["PRE_PRP"],
                    reader.IsDBNull(reader.GetOrdinal("IMG_IMG")) ? null : (string)reader["IMG_IMG"],
                    Attributi(connection, (int)reader["ID_PLUREP"])
                    ));
            }

            return plu; 
        }

这是函数 Attributi,其中 return 每个 Plu

attributes 的 IEnumerable
        public IEnumerable<Plu.Attributi> Attributi(MySqlConnection connection, int idplu)
        {
            var sql = @"QUERY";

            using var cmd = new MySqlCommand(sql, connection);
            cmd.Parameters.AddWithValue("@idplu", idplu);
            cmd.Prepare();

            List<Plu.Attributi> attributi = new List<Plu.Attributi>();

            using MySqlDataReader reader = cmd.ExecuteReader();
            while (reader.Read())
            {
                attributi.Add(new Plu.Attributi(
                        reader.IsDBNull(reader.GetOrdinal("BCKCOL_ATT")) ? null : (string)reader["BCKCOL_ATT"],
                        reader.IsDBNull(reader.GetOrdinal("FORCOL_ATT")) ? null : (string)reader["FORCOL_ATT"],
                        reader.IsDBNull(reader.GetOrdinal("DESCR_ATT")) ? null : (string)reader["DESCR_ATT"]
                        ));
            }

            return null;
        }

您不能将打开的连接与 reader 已经在执行的连接一起使用。在属性中打开一个新连接。

public IEnumerable<Plu.Attributi> Attributi(int idplu)
{
    var sql = @"QUERY";

    using var connection = new MySqlConnection(connectionString)
    {
        connection.Open();
        using var cmd = new MySqlCommand(sql, connection)
        {
            cmd.Parameters.AddWithValue("@idplu", idplu);
            cmd.Prepare();

            List<Plu.Attributi> attributi = new List<Plu.Attributi>();

            using MySqlDataReader reader = cmd.ExecuteReader()
            {
                while (reader.Read())
                {
                    attributi.Add(new Plu.Attributi(
                        reader.IsDBNull(reader.GetOrdinal("BCKCOL_ATT")) ? null : (string)reader["BCKCOL_ATT"],
                        reader.IsDBNull(reader.GetOrdinal("FORCOL_ATT")) ? null : (string)reader["FORCOL_ATT"],
                        reader.IsDBNull(reader.GetOrdinal("DESCR_ATT")) ? null : (string)reader["DESCR_ATT"]
                        ));
            }

            return null;
        }
    }
}

顺便说一句,您对 using 的使用完全无效。在 using 语句之后需要一个块来处理有关 IDisposable 对象的所有内容。

编辑: 显然这是 .NET Core 3.1 的新功能。

对于更一般的情况,我在 MySQL 方面的经验让我总是 "free" 我的 reader 有:

MySqlDataReader reader = cmd.ExecuteReader();
DataTable dataTable = new DataTable();
dataTable.Load(reader);

然后从 DataTable 而不是 MySqlDataReader 开始工作,然后您可以根据需要重用该连接。