为什么在通过 "HasRows" 测试后出现 "no data is present" 错误?

Why am I getting a "no data is present" error after passing the "HasRows" test?

我有这个代码:

Protected Function GetArgValsForCompanyName(coName As String) As String()
    Dim args(2) As String
    Dim sqlConnection1 As New SqlConnection("SERVER=PLATYPUS42;DATABASE=duckbilldata;UID=durante;PWD=pondscum")
    Dim cmd As New SqlCommand
    Dim reader As SqlDataReader

    cmd.CommandText = "select Unit, MemberNo, CustNo from Customers WHERE CompanyName = @CoName"
    cmd.CommandType = CommandType.Text
    cmd.Parameters.Add("@CoName", SqlDbType.VarChar, 50).Value = coName
    cmd.Connection = sqlConnection1
    sqlConnection1.Open()

    reader = cmd.ExecuteReader()
    If reader.HasRows Then
            args(0) = reader.Item(0).ToString()
            args(1) = reader.Item(1).ToString()
            args(2) = reader.Item(2).ToString()
    End If
    reader.Close()
    sqlConnection1.Close()

    Return args
End Function

...在此行失败:

args(0) = reader.Item(0).ToString()

...与:

*System.InvalidOperationException was unhandled
  HResult=-2146233079
  Message=Invalid attempt to read when no data is present.*

怎么会 "HasRows" 却没有数据呢?

注意:当我尝试这个(而不是使用“0”索引)时,它也失败并出现同样的错误:

args(0) = reader.Item("Unit").ToString()

更新

接受的答案在现代应用程序(例如,我的 "sandbox" Windows 表单应用程序)中工作正常,但在旧的应用程序中,例如使用 .NET prehistoric 的古旧网站,它没有- "usings" 显然无法识别;我得到:

Server Error in '/EMS/customerreportingnet' Application.
--------------------------------------------------------------------------------

Compilation Error 
Description: An error occurred during the compilation of a resource required to service this request. 

Please review the following specific error details and modify your source code appropriately. 

Compiler Error Message: BC30203: Identifier expected.

Source Error:

Line 90:         Dim args(2) As String
Line 91: 
Line 92:         Using con As New SqlConnection("SERVER=PLATYPUS42;DATABASE=duckbilldata;UID=durante;PWD=pondscum"),
Line 93:               cmd As New SqlCommand("select Unit, MemberNo, CustNo from Customers WHERE 

CompanyName = @CoName", con)
Line 94: 

--------------------------------------------------------------------------------
Version Information: Microsoft .NET Framework Version:2.0.50727.5485; ASP.NET Version:2.0.50727.5491 

还需要调用 "read";这有效(可以使用返回的字段名称或其索引):

If reader.HasRows Then
    Do While reader.Read
        'args(0) = reader.Item(0).ToString()
        args(0) = reader.Item("Unit").ToString()
        args(1) = reader.Item(1).ToString()
        args(2) = reader.Item(2).ToString()
    Loop
End If

正如您在 中所说,需要调用 .Read

然而 If reader.HasRows 不是必需的。 Do While reader.Read 会处理这个。如果有行则进入循环,否则绕过

作为附加说明,我认为实施 Using:

会有所帮助
Protected Function GetArgValsForCompanyName(coName As String) As String()
    Dim args(2) As String

    Using con As New SqlConnection("SERVER=PLATYPUS42;DATABASE=duckbilldata;UID=durante;PWD=pondscum"),
          cmd As New SqlCommand("select Unit, MemberNo, CustNo from Customers WHERE CompanyName = @CoName", con)

        con.Open()

        cmd.CommandType = CommandType.Text
        cmd.Parameters.Add("@CoName", SqlDbType.VarChar, 50).Value = coName

        Using reader As SqlDataReader = cmd.ExecuteReader

            While reader.Read
                args(0) = reader.Item(0).ToString()
                args(1) = reader.Item(1).ToString()
                args(2) = reader.Item(2).ToString()
            End While

        End Using

    End Using

    Return args
End Function

使用 Using,您不必担心调用 .Close 或对象的处置。我也觉得读起来更好。