无法使用 VB 和 Public 中的 MySqlClient 从数据库获取数据 异步变量不可访问

not able fetch Data from a database using MySqlClient in VB and Public Async Variables are inaccessable

这是我编写的代码,有一次它在访问级别显示 System.Data.Dataset return,但这不是我想要的。 用户名是一个字符串,密码也是一个字符串,访问级别是一个整数。有没有一种更有效的替代方法?您还可以解释一下为什么我会出错,这样我以后就不会 运行 遇到类似的事情了。提前致谢

[错误图片和访问打印的内容][1]

Public Class Login
    Dim Access_level As Integer
    Private Sub Login_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        'TODO: This line of code loads data into the 'Parts.User' table. You can move, or remove it, as needed.
        'Me.UserTableAdapter.Fill(Me.Parts.User)
    End Sub
    Public Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        If TextBox1.Text = "" Or TextBox2.Text = "" Then
            MsgBox("Oops ¯\_(ツ)_/¯ " + Err.Description(), MsgBoxStyle.OkOnly, "Enter Value")
        Else
            Try
                Await getDataSet(TextBox1.Text, TextBox2.Text, Access_level)
                Print(username)
                Print(password)
                If username = TextBox1.Text And password = TextBox2.Text Then
                    Dim Access As Integer = Access_level
                    Print(Access)
                    If Access = 1 Then
                        Me.Hide()
                        AdminMainMenu.Show()
                    Else
                        Me.Hide()
                        MainMenu.Show()
                    End If
                End If
            Catch ex As Exception
                'MsgBox("Oops " + Err.Description(), MsgBoxStyle.OkOnly, "Failed to Open")
                'MsgBox("Incorrect login details", MsgBoxStyle.OkOnly)
                System.Windows.Forms.MessageBox.Show(ex.Message)
            End Try
        End If
        TextBox1.Clear()
        TextBox2.Clear()
    End Sub

    Public Async Function getDataSet(username As String, password As String, Access_level As Integer) As Task(Of DataSet)
        Return Await Task.Factory.StartNew(
            Function()
                Dim connectionString = "server=localhost; userid=root; password=; database=partstest1; CharSet=utf8;"
                Dim commandText = "SELECT Username, Password, Accesslevel FROM `user` WHERE `Username` = '" & username & "' and `Password` = '" & SHA256(password) & "';"
                Using connDB = New MySqlConnection(connectionString), objCmd = New MySqlCommand(), objAdpt = New MySqlDataAdapter()
                    connDB.Open()
                    objCmd.Connection = connDB
                    objCmd.CommandText = commandText
                    objCmd.CommandType = CommandType.Text
                    objAdpt.SelectCommand = objCmd
                    Dim objDs = New DataSet()
                    objAdpt.Fill(objDs)
                    Console.WriteLine(objDs)
                    Return objDs
                End Using
            End Function)
    End Function


  [1]: https://i.stack.imgur.com/g9CIj.png

你不应该需要所有异步的东西来检索一条数据。

数据库代码:

您可以将 .CommandText 和命令连接直接传递给命令的构造函数。

您已有用户名和密码。不要检索不需要的数据。

始终使用参数来避免 Sql 注入并使 sql 语句更易于编写。

我假设 Sha256(password) 是一个自定义函数。

CommandType.Text 是默认值,不必明确指定。

您不需要数据适配器。您不会在此处更新此数据。不管怎样,你的适配器超出了范围,所以它没有价值。

您不需要数据集。您只处理一份数据,而不是多个表。使用 .ExecuteScalar 到 return 结果集第一行的第一列。

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    If TextBox1.Text = "" OrElse TextBox2.Text = "" Then
        MessageBox.Show("Oops ¯\_(ツ)_/¯  both Username and Password must be filled in.", "Enter Value")
        Exit Sub
    End If
    Try
        Access_level = getAccessLevel(TextBox1.Text, TextBox2.Text)
    Catch ex As Exception
        MessageBox.Show(ex.Message)
        Exit Sub
    End Try

    If Access_level = 1 Then
        Me.Hide()
        AdminMainMenu.Show()
    Else
        Me.Hide()
        MainMenu.Show()
    End If
    TextBox1.Clear()
    TextBox2.Clear()
End Sub

Private Function getAccessLevel(username As String, password As String) As Integer
    Dim retVal As Integer
    Dim connectionString = "server=localhost; userid=root; password=; database=partstest1; CharSet=utf8;"
    Using connDB = New MySqlConnection(connectionString),
                    objCmd = New MySqlCommand("SELECT  Accesslevel FROM `user` WHERE `Username` = @Username and `Password` = @Password", connDB)
        objCmd.Parameters.Add("@Username", MySqlDbType.VarChar, 100).Value = username
        objCmd.Parameters.Add("@Password", MySqlDbType.VarChar, 100).Value = SHA256(password)
        connDB.Open()
        retVal = CInt(objCmd.ExecuteScalar())
    End Using
    Return retVal
End Function

编辑

Private Function getAccessLevel(username As String, password As String) As Integer
    Dim retVal As Object
    Dim connectionString = "server=localhost; userid=root; password=; database=partstest1; CharSet=utf8;"
    Using connDB = New MySqlConnection(connectionString),
                objCmd = New MySqlCommand("SELECT  Accesslevel FROM `user` WHERE `Username` = @Username and `Password` = @Password", connDB)
        objCmd.Parameters.Add("@Username", MySqlDbType.VarChar, 100).Value = username
        objCmd.Parameters.Add("@Password", MySqlDbType.VarChar, 100).Value = SHA256(password)
        connDB.Open()
        retVal = objCmd.ExecuteScalar()
    End Using
    If retVal Is Nothing Then
        Return -1
    Else
        Debug.Print(CInt(retVal).ToString)
        Return CInt(retVal)
    End If
End Function

按钮代码...

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    If TextBox1.Text = "" OrElse TextBox2.Text = "" Then
        MessageBox.Show("Oops ¯\_(ツ)_/¯  both Username and Password must be filled in.", "Enter Value")
        Exit Sub
    End If
    Try
        Access_level = getAccessLevel(TextBox1.Text, TextBox2.Text)
    Catch ex As Exception
        MessageBox.Show(ex.Message)
        Exit Sub
    End Try

    If Access_level = 1 Then
        Me.Hide()
        AdminMainMenu.Show()
    ElseIf Access_Level = 0 Then
        Me.Hide()
        MainMenu.Show()
    Else
        MessageBox.Show("Sorry, No match")
    End If
    TextBox1.Clear()
    TextBox2.Clear()
End Sub

将 retVal 更改为对象。

从 objCmd.ExecuteScalar()

中删除了 CInt

什么都不检查,returned -1 Else CInt(RetVal)