如何在阅读器关闭之前返回 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 返回