我有一张用于用户屏幕的表。
用户ID-屏幕ID-烫发
当使用UserID和ScreenID打开表单时,我需要隐藏控件,并且无法使用带有条件的循环。
这是我的代码:
Try
Dim da As New SqlDataAdapter
Dim ds As New DataSet
If dbconnect.State = ConnectionState.Closed Then dbconnect.Open()
da = New SqlDataAdapter("SELECT * FROM UserScreens WHERE UserID='" & UserID & "'", dbconnect)
da.Fill(ds, "Table")
If ds.Tables(0).Rows.Count > 0 Then
Dim M As DataRow = ds.Tables(0).Rows(0)
For Each ctrl As Control In Ribbon1.Controls
ctrl.Visible = M.Item("Perm")
Next
'DocIDtxt.Text = M.Item("DOCID")
End If
Catch ex As Exception
If dbconnect.State = ConnectionState.Open Then dbconnect.Close()
MsgBox(ex.ToString)
End Try
答案 0 :(得分:0)
我总是首先担心连接问题。来自MS文档
“与select命令关联的IDbConnection对象必须有效,但不必打开。如果IDbConnection在调用Fill之前关闭,则先打开它以检索数据,然后关闭。如果连接是打开的在调用Fill之前,它保持打开状态。”
这意味着您在.Fill方法之前打开了连接,因此它将保持打开状态。坏!代码关闭连接的唯一方法是出现错误。在Try ... End Try中使用.Close的Final部分可以解决问题,但最好使用Using ... End Using。即使出现错误,此块也可以确保关闭并正确放置对象。当对象具有Dispose方法时,它可能具有必须清除的非托管资源。
接下来,打开“严格选项”。指出潜在的运行时错误将有很大帮助。
第三,请始终使用参数。
请参阅内嵌说明和评论。
Private Sub OpCode()
Try
'A DataTable does not have a Dispose() method so it will fall
'out of scope and be garbage collected.
Dim dt As New DataTable
'SqlConnection has a Dispose() method so use Using
Using cn As New SqlConnection("Your connection string")
'SqlCommand has a Dispose() method so use Using
Using cmd As New SqlCommand("SELECT * FROM UserScreens WHERE UserID= @UserID", cn)
'Always use Parameters. Never concatenate strings in SQL statements.
cmd.Parameters.Add("@UserID", SqlDbType.VarChar).Value = UserID
cn.Open()
'SqlDataReader has a Dispose() method so use Using
Using dr As SqlDataReader = cmd.ExecuteReader
dt.Load(dr)
End Using
End Using
End Using
If dt.Rows.Count > 0 Then
Dim M As DataRow = dt.Rows(0)
For Each ctrl As Control In Ribbon1.Controls
'If Perm is not a boolean this line of code can't work
ctrl.Visible = CBool(M.Item("Perm"))
Next
'DocIDtxt.Text = M.Item("DOCID")
End If
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub