【问题标题】:IDataReader empties when viewing for a second time第二次查看时 IDataReader 清空
【发布时间】:2008-11-03 18:36:55
【问题描述】:

尝试使用 MySql .net 连接器读取一些数据时,我遇到了一些非常奇怪的事情。代码如下:

IDataReader reader = null;

using (MySqlConnection connection = new MySqlConnection(this.ConnectionString))
{
    String getSearch = "select * from organization";
    MySqlCommand cmd = new MySqlCommand(getSearch, connection);
    cmd.CommandType = CommandType.Text;

    connection.Open();
    reader = cmd.ExecuteReader();

    while (reader.Read())
    {
        // response write some stuff to the screen (snipped for brevity)
    }
}

如果我在 ExecuteReader 之后放置一个断点并在 Visual Studio 中展开结果视图(将鼠标悬停在阅读器上并展开),我可以看到查询返回的行。如果我随后让它关闭并再次展开结果视图,我会收到消息“枚举未产生结果”。

阅读器的内容似乎在被查看后立即被重置。

至于我们的尝试:
- SQL 直接在 DB 上运行良好
- 将查询结果直接绑定到数据网格只会返回一个空的数据网格
- 获得了最新版本的 .net 连接器
- 尝试在两台不同的机器上排除任何本地错误

到目前为止,没有任何效果。

如果有人能提供任何想法或建议,他们将不胜感激。

【问题讨论】:

    标签: .net mysql-connector


    【解决方案1】:

    据我了解,SqlDataReader 旨在用于一次性枚举您返回的数据。一旦您对结果进行了一次循环,该对象就完成了它的职责。这里有一些解决这个问题的想法,其中一个或另一个可以根据您的需要为您解决这个问题:

    1. 在需要时重新执行查询以生成另一个 SqlDataReader

    2. 不要使用 SqlDataReader,而是将原始查询的结果存储到 System.Data.DataTable 中,然后您可以根据需要重新读取和操作数据。

    希望这会有所帮助!

    亚当

    【讨论】:

    • 感谢您的回复。这是有道理的,是的。已经看了好几个小时,但从未发生过。我尝试在不暂停的情况下运行它,以确保它只读取一次但没有任何运气。虽然可能是别的东西,但由于我现在每天工作 11 小时,所以我明天必须进行测试。
    【解决方案2】:

    由于数据读取器会读取信息,因此您的 using 块会在将读取器的值分配给变量后立即关闭与读取器的连接。 Here is an article 向您展示了一些代码示例,它们可能会将您带到您需要的地方。

    关键是在尝试从阅读器读取数据时,连接必须打开。

    【讨论】:

    • 您好,感谢您的回复。阅读器执行下方的应用程序代码中有几行(只是基本的同时读取/响应写入),但第一次读取永远不会起作用。一旦读取器被访问,它就会清空。除非我弄错了,此时连接仍处于打开状态。
    • 在您的示例中,当 using 语句结束时,连接将关闭。因此,如果它在 Using 块之外,则连接关闭
    • 嗨,是的,我应该将它添加到代码示例中。我现在已经这样做了;很抱歉造成混乱。
    • 啊,考虑到这一点,我会相信波格丹在这一点上是正确的,但我从未体验过他所说的话。简单的测试方法是在 while 循环内的某处设置断点。
    【解决方案3】:

    解释如下:

    这是因为,您已经在调试器中循环了一次阅读器(第一次展开视图时)。这是阅读器的工作方式,据我所知,除了重新执行选项之外,没有办法重新设置阅读器以重新开始阅读:

    你只需要再次运行 cmd.ExecuteReader(); 线(右 单击源并使用“设置 下一条语句”菜单选项)。

    这是数据读取器的行为。如果您已经循环通过它,您将无法返回。您必须再次执行该命令并检索一个新命令。

    如果您需要在关闭阅读器后使用您的数据,您可以选择使用Typed DataSet,或者Adam 的answer 中指定的无类型DataSet

    顺便说一句,这里有一些optimizations你可以做:

    • 将阅读器移入 Connection 使用块来制作它 完成后超出范围 使用它(一旦你使用 块,连接将被关闭 而且你无论如何都无法使用它,所以把它放在外面没有意义)
    • 运行ExecuteReader 另一个using 块(因为它实现了IDisposable)并使用Sql Command 做同样的事情(同样的IDisposable 接口)
    • 不检索 数据库中的所有字段

    【讨论】:

      猜你喜欢
      • 2011-12-06
      • 2017-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多