1

我觉得很难在这里提出这个问题,因为我认为我无法为这个社区提供任何回报。我目前正在编写一个应用程序,一旦启动,它就会要求用户登录。如果用户输入的数据与数据库中的数据匹配,则用户已登录。然后应用程序从数据库中获取有关用户的数据,例如用户 ID、姓名、角色。

现在我希望这些信息在应用程序中广泛使用。我现在的情况:

  • 解决方案
    • 可执行文件(主项目)
    • Database.dll(类等)

在 database.dll 中,我有以下类:

Public Class SessionProfile
Public _gebruikersID As String
Public _gebruikersNaam As String
Public _gebruikersRole As String

Public Property gebruikersID() As String
    Get
        Return _gebruikersID
    End Get

    Set(ByVal value As String)
        _gebruikersID = value
    End Set
End Property

Public Property gebruikersNaam() As String
    Get
        Return _gebruikersNaam
    End Get

    Set(ByVal value As String)
        _gebruikersNaam = value
    End Set
End Property

Public Property gebruikersRole() As String
    Get
        Return _gebruikersRole
    End Get

    Set(ByVal value As String)
        _gebruikersRole = value
    End Set
End Property
End Class

在我的主要可执行文件中,我将此类称为如下:Dim SessionProfile As New Database.SessionProfile()在我的登录表单中,我使用以下代码设置设置器:

If loginResult = 1 Then
     SessionProfile.gebruikersID = SQLHook.Results("SELECT * FROM tblgebruikers WHERE GebruikersNaam = '" & TextGebruikersNaam.Text.Replace("'", "''") & "'", "GebruikersID")
     SessionProfile.gebruikersNaam = SQLHook.Results("SELECT * FROM tblgebruikers WHERE GebruikersNaam = '" & TextGebruikersNaam.Text.Replace("'", "''") & "'", "gebruikersNaam")
     SessionProfile.gebruikersRole = SQLHook.Results("SELECT * FROM tblgebruikers WHERE GebruikersNaam = '" & TextGebruikersNaam.Text.Replace("'", "''") & "'", "gebruikersRole")
     DialogResult = DialogResult.OK
Else
     SessionProfile.gebruikersID = ""
     SessionProfile.gebruikersNaam = ""
     SessionProfile.gebruikersRole = ""
     DialogResult = DialogResult.NO
End If

现在我回到我的主要形式并使用例如MsgBox(SessionProfile.GebruikersNaam),我没有得到任何回报。

这个理论不起作用是有原因的还是我做错了什么?查询很好,因为如果您将它们调暗为字符串并将它们添加到 msgbox 中,它会显示正确的文本。

有人可以帮我解决我的问题吗?

4

3 回答 3

1

您发布的代码似乎没有任何问题,可以解释您面临的问题,因此您可能希望将代码发布在您的主表单和登录表单上,以便我们看看有什么问题正在进行。

但是,如果您有时间进行快速代码审查,我建议您将本地字段的范围限定为类私有,因为您通过公共属性公开它们。这将有助于“保护”字段中的数据免受外部来源修改数据的影响,而无需访问您的设置器。

所以这:

Public Class SessionProfile
Public _gebruikersID As String
Public _gebruikersNaam As String
Public _gebruikersRole As String

Public Property gebruikersID() As String
    Get
        Return _gebruikersID
    End Get

    Set(ByVal value As String)
        _gebruikersID = value
    End Set
End Property ...

真的应该是这样的:

Public Class SessionProfile
'Limit the scope to be private to the class;
private _gebruikersID As String
private _gebruikersNaam As String
private _gebruikersRole As String

Public Property gebruikersID() As String
    Get
        Return _gebruikersID
    End Get

    Set(ByVal value As String)
        _gebruikersID = value
    End Set
End Property ...

其次,也许更重要的是,您应该真正使用参数化的 sql 语句,而不是用户输入文本的字符串连接。我知道您正在使用已安装的应用程序,但仍然是一个很好的做法。

这些建议都不会帮助您解决最初的问题,因此请务必在有问题的两种表单上发布有关代码的更多详细信息,以便我们解决手头的问题。

于 2013-02-28T21:01:09.347 回答
1

如果我正确理解您的情况,您将处于以下情况。

在主可执行文件中,您在某处声明了一个变量(我将更改名称以便更好地解释)

Dim currProfile As New Database.SessionProfile() 

这意味着您已经创建了一个 SessionProfile 类型的变量,现在您调用 frmLogin

Dim form1 As new frmLogin()
if DialogResult.OK = form1.ShowDialog() then
    MsgBox(curProfile.GebruikersNaam) ' shows nothing'

在 frmLogin 你已经声明了一个新的(不同的)变量

Dim profile As New Database.SessionProfile()

这个变量是一个不同的变量,与主窗体中声明的变量没有任何共享,设置它的属性并不意味着另一个 SessionProfile 变量看到这些变化。
您需要将第一个变量传递给 frmLogin。也许在构造函数中。

Dim form1 As new frmLogin(currProfile)
if DialogResult.OK = form1.ShowDialog() then
    MsgBox(curProfile.GebruikersNaam) ' shows the name'

并在 frmLogin 构造函数中接收并存储传入的变量

Dim profile As SessionProfile = Nothing
Public Sub New(ByVal p As SessionProfile)
    profile = p
    InitializeComponent()
End Sub

现在,当您在内部 (frmLogin) 配置文件变量上设置属性时,您正在设置主窗体中使用的同一实例的属性。
顺便说一句,避免用你的类的同名来调用你的变量。真的很混乱

于 2013-02-28T20:57:17.467 回答
0

如果一次只能返回一个值,您的数据库查询似乎过于笼统。您只需进行一次查询即可获取所需的所有数据:

Dim sp As SessionProfile = Nothing

If loginResult = 1 Then
    Dim sqlConnStr = "your sql connection string"

    Dim nResults As Integer = 0
    Using sqlConn = New SqlConnection(sqlConnStr)

        ' N.B. always select only what you need, and always select explicitly
        Dim sql = "SELECT GebruikersID, gebruikersNaam, gebruikersRole FROM tblgebruikers WHERE GebruikersNaam = @Naam"

        Dim sqlCmd = New SqlCommand(sql, sqlConn)
        sqlCmd.Parameters.AddWithValue("@Naam", TextGebruikersNaam.Text)

        sqlConn.Open()

        Dim rdr = sqlCmd.ExecuteReader
        While rdr.Read
            sp = New SessionProfile With {.gebruikersID = rdr.GetString(0), _
                                          .gebruikersNaam = rdr.GetString(1), _
                                          .gebruikersRole = rdr.GetString(2)}

            nResults += 1
        End While

    End Using

    If nResults <> 1 Then
        Throw New Exception(String.Format("User {0} is in database more than once.", TextGebruikersNaam.Text))
    End If

    If sp IsNot Nothing Then
        ' sp now contains the session profile
    End If

End If

通过使用 SQL 参数,您无需对撇号等字符进行特殊处理 - 请注意该代码如何不使用 .Replace("'", "''")。

于 2013-02-28T21:50:53.287 回答