DBReader 有行但 Read() 返回 false

Posted

技术标签:

【中文标题】DBReader 有行但 Read() 返回 false【英文标题】:DBReader has rows but Read() returns false 【发布时间】:2016-11-03 18:56:19 【问题描述】:
using (var conn = new SqlConnection(connectionString))

    var cmd = new SqlCommand("SELECT * FROM mySchema.MyTable", conn);
    conn.Open();
    var reader = cmd.ExecuteReader();
    while(reader.Read())
    ...

在调试器中,我可以看到我的阅读器有一行 - 我可以看到返回的数据 - 但 reader.Read 正在返回 false,所以我的处理代码没有被调用。

这似乎是非常基本的“从数据库表中读取行”的东西,所以我错过了什么?我应该直接查看读者的行数据还是什么?

【问题讨论】:

您在调试器中究竟是如何看到这一行的?你看的是哪个楼盘?调试器是否已经调用了Read(),所以当你的代码调用它时它是false 听起来调试器已经读取了所有数据,然后您的代码检测到没有更多数据。如果您不使用调试器,这是否有效? 说真的,调试器可以这样修改代码的行为吗?就像我在reader 上展开“结果视图”一样,它会运行while(reader.Read())... 循环? 如果你看到了结果,如果不是这样读出来,调试器应该如何得到它们?它不会启动第二个查询... 嗯,调试器的全部意义在于成为一个沉默的观察者,确定吗?逐行执行你的程序,等等…… 【参考方案1】:

如果让调试器显示结果,它会读出阅读器并枚举结果。

查看调试器窗口中的注释:

结果视图:展开结果视图将枚举 IEnumerable

所以你的调试器已经读出了所有结果,如果你进入reader.Read(),就没有更多的行要读取,Read() 返回false


我只是通过小测试复制了它。当我的调试器读取结果时,我的代码无法再读取它们。如果我不让调试器显示它们,我的代码可以读取它们。 (qed)

【讨论】:

这似乎是个问题,但调试器破坏了程序的行为对我来说仍然很疯狂......我可以检查返回的结果,或者我可以使用它们,但不能同时使用它们!有没有不傻的方法来避免这个问题? @Mr.Boy 在这种特殊情况下我不这么认为。另一方面,你为什么需要。要进行调试,您可以简单地在 Read() 循环内设置断点。我想你可以很确定SqlDataReader 工作正常,所以我认为不需要在你自己的阅读循环之外/之前查看结果。 @RenéVogt,你拯救了我的一天 :) 赞。【参考方案2】:

您可以尝试SELECT 1; 来测试您的读者。 你有 SqlManagement Studio 吗?测试查询。

这是工作。

 using (var conn = new SqlConnection(connectionString))
        
            var cmd = new SqlCommand("select 1", conn);
            conn.Open();
            var reader = cmd.ExecuteReader();
            while(reader.Read())
            
                string a = "teste";
            
        

【讨论】:

【参考方案3】:

这可能对某人有帮助。就我而言,我忘了使用

 cmd.CommandType = System.Data.CommandType.StoredProcedure

所以,reader.HasRows() 或 reader.Read() 返回 false。

【讨论】:

【参考方案4】:

将阅读器类型 var 更改为 SqlDataReader reader = command.ExecuteReader(); 并尝试一下。它会起作用。

我有mysql的示例代码

using (MYSQLCON)
        
            using (MySqlDataReader sdr = sqlcmd.ExecuteReader())
            using (YourWriter)
            
                String Header = null;
                String Content = null;

                for (int i = 0; i <= sdr.FieldCount - 1; i++)
                
                    Header = Header + sdr.GetName(i).ToString() + ",";
                
                YourWriter.WriteLine(Header);
                while (sdr.Read())

                    for (int i = 0; i <= sdr.FieldCount - 1; i++)
                    
                        Content = Content + sdr[i].ToString() + ",";
                        if (i == sdr.FieldCount - 1)
                        
                            YourWriter.WriteLine(Content);
                            Content = null;
                        
                    
            
        

【讨论】:

var 只是语法糖。编译器知道它在SqlDataReader 上运行。这与 OP 观察到的行为无关。

以上是关于DBReader 有行但 Read() 返回 false的主要内容,如果未能解决你的问题,请参考以下文章

Python Pandas read_csv 跳过行但保留标题

pandas使用read_csv读取数据使用skiprows参数跳过指定的数据行但保留表头pandas使用to_csv函数将dataframe保存为gzip压缩文件

更有效的方法来迭代我的数据(DbReader/DataSet)

MySQL REPLACE 影响 0 行但 WHERE ... LIKE 返回 90

将我的数据从 access 2003 db 获取到 c# 的问题(dbReader.GetString 错误)

Query.getResultList() 即使sql表有行也不返回结果