如何在阅读器关闭之前返回 MySqlDataReader [重复]

Posted

技术标签:

【中文标题】如何在阅读器关闭之前返回 MySqlDataReader [重复]【英文标题】:How to return a MySqlDataReader before the reader is closed [duplicate] 【发布时间】:2012-07-25 20:28:36 【问题描述】:

好的,我的代码目前是:

    public mysqlDataReader CreateQuery(string queryString, string connectionString )
    

        using (MySqlConnection connection = new MySqlConnection(connectionString))
        
            using (MySqlCommand command = new MySqlCommand(queryString, connection))
            
                command.Connection.Open();
                command.ExecuteNonQuery();

                MySqlDataReader reader = command.ExecuteReader();
                return reader;
            
        
    

在另一个函数中,我有:

using(MySqlDataReader readers = _connection.CreateQuery(query, connectString))

目前,在这种形式下,当我将阅读器返回到阅读器时,没有任何价值。我已经通过并验证了在返回时,读者的信息是正确的。然而,读者没有价值。我可能错过了一些完全愚蠢的东西。但是,我们将不胜感激任何和所有的帮助。谢谢!

【问题讨论】:

您在返回阅读器之前关闭了底层连接。 您是否尝试过返回IEnumerable<IDataRecord>using (IDataReader rdr = command.ExecuteReader()) while (rdr.Read()) yield return (IDataRecord)rdr; @Lee:是的,我已经想通了。如果可能的话,我只是想弄清楚如何不这样做。 @TimSchmelter:我没试过。但我现在会。我从来没有听说过 IDataRecord,所以这可能需要我一些。但我会更新。谢谢。 【参考方案1】:

使用 using 命令,您的代码实际上将处理连接,并将控制权之前的命令返回给调用者。本质上,您的连接对象和您在 using 语句中创建的命令对象在调用代码能够使用它之前就已被释放,因此它不再可用。

您可能希望对查询结果而不是阅读器本身做一些事情。也许将其加载到表格中?比如:

public DataTable CreateQuery(string queryString, string connectionString )
    
        DataTable results =  new DataTable("Results");
        using (MySqlConnection connection = new MySqlConnection(connectionString))
        
            using (MySqlCommand command = new MySqlCommand(queryString, connection))
            
                command.Connection.Open();
                command.ExecuteNonQuery();

                using (MySqlDataReader reader = command.ExecuteReader())
                    results.Load(reader);
            
        
       return results;
    

【讨论】:

最后,我最终使用了类似的东西。我仍然得到我的信息,并且阅读器/连接正常关闭。谢谢。 -1,DataTable 没有Fill 方法。相反,您一定是指Load。您可以使用 Fill 执行相同操作,但使用 DbDataAdapter【参考方案2】:

您可以返回IEnumerable<IDataRecord>,而不是返回Datareader 或将所有记录复制到内存中的DataTable 中作为一个整体返回,这是DataReader 记录实现的基本接口。

所以这应该可以工作,因为yield 会导致Connection 保持活动状态:

public IEnumerable<IDataRecord> CreateQuery(string queryString, string connectionString)

    using (MySqlConnection connection = new MySqlConnection(connectionString))
    
        using (MySqlCommand command = new MySqlCommand(queryString, connection))
        
            command.Connection.Open();
            using (var reader = command.ExecuteReader())
            
                while (reader.Read())
                
                    yield return (IDataRecord)reader;
                
            
         
    

例如,如果您只想获取前 5 条记录:

var records = CreateQuery("SELECT * FROM ais.country;", Properties.Settings.Default.MySQL).Take(5);
foreach (IDataRecord rec in records)

    String country = rec.GetString(rec.GetOrdinal("Name"));

【讨论】:

这个问题是调用 CreateQuery() 的函数使用来自查询的数据来创建基于列的列表。我有 12 个列表,我试图从一个查询中填充。 @KevinH.: 你如何填充列表(什么样的列表?),你有什么问题? 最初,我用:pastebin.com/rBDay0Ru 填充它们。我可以对记录进行 foreach,并填充类似于您所拥有的每个列表:pastebin.com/F1D2qeqX。但我不确定它有多正确。我的程序编译并完成了它应该做的一切。但是我显示的一些项目不正确。我刚刚进行了第一次测试,所以我还不知道它哪里出了问题。很快就会更新。 我现在的问题是,我正在使用列表中的信息进行一些比较,并将特定数据添加到另一个列表中。例如,我应该在特定列表中获得 1918 个条目,但我只获得 1352 个。 注意:你不需要处理DataTables(删除using)。您必须循环 DataTable 的行并将适当的字段添加到您的列表中。我的流(!)方法在您的pastebin 中看起来不错。展示你的比较。也许你应该在 dbms 中做这样的比较。

以上是关于如何在阅读器关闭之前返回 MySqlDataReader [重复]的主要内容,如果未能解决你的问题,请参考以下文章

在关闭连接之前关闭阅读器

如何在 SqlDataReader 之前知道或获取数组大小?并将其作为 json 返回

如何实现“return true;”?错误:“消息端口在收到响应之前关闭。”

如何在关闭 Qt 控制台应用程序之前运行我的析构函数?

数据仓库教程 [关闭]

是否有接收阅读的API? [关闭]