2

我有这个代码:

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()

更新

公认的答案在现代应用程序(例如,我的“沙盒”Windows 窗体应用程序)中运行良好,但在旧应用程序中,例如使用 .NET 史前的陈旧、陈旧的网站,则不能——“使用”是显然无法识别;我得到:

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 
4

2 回答 2

3

正如您在回答中所说,需要致电.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或处理对象。我也觉得它读起来更好。

于 2017-03-21T17:24:10.927 回答
0

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

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
于 2017-03-21T17:03:15.940 回答