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

私があなたの状況を正しく理解しているなら、あなたは次のシナリオにいます。

メインの実行可能ファイルで、どこかで変数を宣言します(わかりやすくするために名前を変更します)

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 に答える
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 に答える
0

一度に1つの値しか返すことができない場合、データベースクエリは一般的すぎるようです。必要なすべてのデータを取得するには、1つのクエリを実行するだけで済みます。

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 に答える