SqlDataReader.Read 不像宣传的那样工作? [英] SqlDataReader.Read Not Working As Advertised?

查看:26
本文介绍了SqlDataReader.Read 不像宣传的那样工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我在 ADO.NET 中运行一个我知道返回单行的查询.我的代码的相关部分如下所示:

So I'm running a query in ADO.NET that I know returns a single row. The relevant portion of my code looks like:

SqlCommand sqc = new SqlCommand();
sqc.Connection = new SqlConnection("connection string");
sqc.CommandText = "SELECT A, B FROM C WHERE D=@d";
sqc.Parameters.AddWithValue("@d", "d");
sqc.Connection.Open();
SqlDataReader rdr = sqc.ExecuteReader();
bool boolio = rdr.Read();
String a = (String)rdr["A"];

当我运行这个时,我在最后一行得到一个异常,抱怨我试图读取没有数据的地方.

When I run this, I get an exception on the final line, complaining that I'm trying to read where there's no data.

当我在 VS 中逐步执行此操作时,我会在 rdr.Read() 行执行之前检查 rdr,我可以看到我想要的数据位于读取器中.然后我调用 rdr.Read() 结果为 FALSE,表示没有更多数据可供我读取.当我再次检查 rdr 时,内部的 ResultsView 是空的.

When I step through this in VS I inspect rdr before the rdr.Read() line executes and I can see the data I want is sitting in the reader. Then I call rdr.Read() and the result is FALSE, indicating there is no more data for me to read. When I inspect rdr again, the internal ResultsView is empty.

我意识到我可以通过放弃对 Read() 的调用来获取我的数据但是:这种行为与 MSDN 文档 明确指出SqlDataReader 的默认位置在第一条记录之前.因此,您必须调用 Read 来开始访问任何数据.".这也与我在网上找到的每个 SqlDataReader 用法示例相反,例如 这个问题似乎只是为了嘲弄我.

I realize I can get my data simply by discarding the call to Read() BUT: this behaviour is contrary to the MSDN documentation which explicitly says "The default position of the SqlDataReader is before the first record. Therefore, you must call Read to begin accessing any data.". It is also contrary to every example of SqlDataReader usage I've found on the web such as this SO question which seems to exist only to taunt me.

请注意,我已经针对 .NET 3.5 和 .NET 4.5 测试了我的代码,结果相同.

Note that I've tested my code against .NET 3.5 and .NET 4.5 with identical results.

我错过了什么吗?ADO.NET 中是否存在错误?任何输入表示赞赏!

Am I missing something? Is there a bug in ADO.NET? Any input is appreciated!

更新1:我在最后一行得到的实际异常是:

UPDATE 1: The actual exception I get on the last line is:

System.Data.dll 中发生类型为System.InvalidOperationException"的未处理异常

An unhandled exception of type 'System.InvalidOperationException' occurred in System.Data.dll

附加信息:不存在数据时尝试读取无效.

Additional information: Invalid attempt to read when no data is present.

更新 2:

因为 Nathan Skerl 无法重现这种行为,并发布了经过验证的工作代码,但后来我失败了,我怀疑我们运行的平台可能存在问题.作为记录,我使用的是 Windows 7 Professional(64 位)Service Pack 1,并针对 .NET Framework 3.5 和 4.5 编译了我的项目,结果相同.如果有任何我没有包含的相关信息,请告诉我,我会添加.

Because Nathan Skerl was unable to reproduce this behavior, and posted verified working code which subsequently failed for me, I suspect there may be an issue with the platforms we're running on. For the record I am using Windows 7 Professional (64-bit) Service Pack 1 and have compiled my project against .NET Framework 3.5 and 4.5 with the same results. If there is any relevant information I have failed to include please let me know and I will add it.

推荐答案

UPDATE:经过一些故障排除后,我们意识到由于在调试器中通过展开结果视图(其中调用 Read() 并使用这些行.

UPDATE: After some troubleshooting we realized the reader was empty due to inspecting the reader in the debugger by expanding the Results View (which calls to Read() and consumes the rows).

使用您的代码,我在 Linqpad 中运行了此单元测试,结果符合预期,初始 reader.read() 前进到ONE"行,第二次调用TWO"行.您能否通过这样的测试重现您的错误:

Using your code I ran this unit test in Linqpad and the results were as expected, the initial reader.read() advances to row "ONE", and the second call to row "TWO". Can you reproduce your error with a test such as this:

SqlCommand sqc = new SqlCommand();
sqc.Connection = (SqlConnection)this.Connection;
sqc.CommandText = "SELECT 'ONE' [A] union all select 'TWO' order by [A] asc;";
sqc.Parameters.AddWithValue("@d", "d");
sqc.Connection.Open();
SqlDataReader rdr = sqc.ExecuteReader();

bool boolio = rdr.Read();
String a = (String)rdr["A"];
a.Dump();

rdr.Read();
String b = (String)rdr["A"];
b.Dump();

你能告诉我们这个模式返回什么吗:

Can you also show us what this pattern returns:

using (SqlConnection connection = (SqlConnection)this.Connection)
using (SqlCommand sqc = new SqlCommand("select 'ONE' as [A] union all select 'TWO';", connection))
{
   connection.Open();

   using (SqlDataReader rdr = sqc.ExecuteReader())
   {
       while (rdr.Read())
       {
          Console.WriteLine(String.Format("{0}", (String)rdr["A"]));
       }
   }
}

这篇关于SqlDataReader.Read 不像宣传的那样工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆