我对在visualstudio(最近从msaccess转换过来)中开发应用程序还是相当陌生的,我正在vb.net中编写代码。我的问题是关于如何根据对另一个组合框的选择来更改第二个组合框。我的所有结果都存储在单独的sql server数据库中。
当我的表格被调用时,以下将执行;
Public Sub New(ByVal _PartID As String)
InitializeComponent() 'Required at the begining of calling a new form'
LoadCombobox(cboArea, "SELECT [ID], [Name], [MRPShow] FROM [LocationArea] WHERE [MRPShow] = 1", "Name", "ID")
cboArea.SelectedValue = 0
cboBay.SelectedValue = 0
LoadPartData(_PartID)
End Sub
Public Sub LoadCombobox(_cbo As ComboBox, _query As String, _displayMember As String, _valueMember As String)
Dim SQL As New SQLControl
_cbo.Items.Clear()
SQL.ExecQuery(_query)
If SQL.HasException(True) Then Exit Sub
_cbo.DataSource = SQL.DBDT
_cbo.DisplayMember = _displayMember
_cbo.ValueMember = _valueMember
End Sub
Public Sub LoadPartData(_ID As String)
Sql.AddParam("@ID", _ID)
Sql.ExecQuery("SELECT * FROM [Part] " &
"WHERE ID = @ID")
If Sql.RecordCount < 1 Then
MsgBox("No item found.")
Exit Sub
End If
For Each r As DataRow In Sql.DBDT.Rows
txtID.Text = r("ID").ToString()
txtMRPID.Text = r("MRP_ID").ToString()
txtPartName.Text = r("PartName").ToString()
txtManufacturer.Text = r("Manufacturer").ToString()
txtManufacturerPartNo.Text = r("PartNumber").ToString()
cboVendor1.SelectedValue = r("Vendor1")
txtWebsiteVendor1.Text = r("Vendor1Link").ToString()
cboVendor2.SelectedValue = r("Vendor2")
txtWebsiteVendor2.Text = r("Vendor2Link").ToString()
cboVendor3.SelectedValue = r("Vendor3")
txtWebsiteVendor3.Text = r("Vendor3Link").ToString()
cboArea.SelectedValue = r("LocationArea")
cboBay.SelectedValue = r("LocationBay")
cboRack.SelectedValue = r("LocationRack")
cboPartAssembly.SelectedValue = r("PartAssembly")
txtDrawingNo.Text = r("DrawingNumber").ToString()
txtImagePath.Text = r("Image").ToString()
Next
If Not String.IsNullOrEmpty(txtWebsiteVendor3.Text) Then
Process.Start(txtWebsiteVendor3.Text)
End If
End Sub
我的sqlcontrol类的代码段
Imports System.Data.SqlClient
Public Class SQLControl
Private DBCon As New SqlConnection("---HIDDEN---")
Private DBCmd As SqlCommand
' DB DATA
Public DBDA As SqlDataAdapter
Public DBDT As DataTable
' QUERY PARAMETERS
Public Params As New List(Of SqlParameter)
' QUERY STATISTICS
Public RecordCount As Integer
Public Exception As String
Public Sub New()
End Sub
' ALLOW CONNECTION STRING OVERRIDE
Public Sub New(ConnectionString As String)
DBCon = New SqlConnection(ConnectionString)
End Sub
' EXECUTE QUERY SUB
Public Sub ExecQuery(Query As String, Optional ReturnID As Boolean = False)
' RESET QUERY STATS
RecordCount = 0
Exception = ""
Try
DBCon.Open()
' CREATE DB COMMAND
DBCmd = New SqlCommand(Query, DBCon)
' LOAD PARAMS INTO DB COMMAND
Params.ForEach(Sub(p) DBCmd.Parameters.Add(p))
' CLEAR PARAM LIST
Params.Clear()
' EXECUTE COMMAND & FILL DATASET
DBDT = New DataTable
DBDA = New SqlDataAdapter(DBCmd)
RecordCount = DBDA.Fill(DBDT)
If ReturnID = True Then
Dim ReturnQuery As String = "SELECT @@IDENTITY As LastID;"
DBCmd = New SqlCommand(ReturnQuery, DBCon)
DBDT = New DataTable
DBDA = New SqlDataAdapter(DBCmd)
RecordCount = DBDA.Fill(DBDT)
End If
Catch ex As Exception
' CAPTURE ERROR
Exception = "ExecQuery Error: " & vbNewLine & ex.Message
Finally
' CLOSE CONNECTION
If DBCon.State = ConnectionState.Open Then DBCon.Close()
End Try
End Sub
' ADD PARAMETERS
Public Sub AddParam(Name As String, Value As Object)
Dim NewParam As New SqlParameter(Name, Value)
Params.Add(NewParam)
End Sub
' ERROR CHECKING
Public Function HasException(Optional Report As Boolean = False) As Boolean
If String.IsNullOrEmpty(Exception) Then Return False
If Report = True Then MsgBox(Exception, MsgBoxStyle.Critical, "Exception:")
Return True
End Function
End Class
因此,我希望实现的是当[cboarea]值更改时,下一个组合框[cbobay]将更新为以下内容:;
Private Sub cboArea_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cboArea.SelectedIndexChanged
cboBay.SelectedValue = 0
Try
SQL.AddParam("@SelectedValueOfcboArea", cboArea.SelectedValue)
SQL.ExecQuery("SELECT [ID], [Name], [LocationAreaID] FROM [LocationBay] WHERE [LocationAreaID] = @SelectedValueOfcboArea")
If SQL.HasException(True) Then Exit Sub
cboBay.DataSource = SQL.DBDT
cboBay.DisplayMember = "Name"
cboBay.ValueMember = "ID"
Catch ex As Exception
End Try
End Sub
上面的内容似乎工作正常,但是当我第一次打开带有特定partid的表单时,我收到以下错误消息;
我相信这些都是初始化代码的错误,在初始化代码中,部件数据被加载到每个控件中,因此调用onvaluechanged事件,该事件不断抛出异常错误,但是我正在努力确定如何解决这个问题,因为我说的是,在加载表单和用户执行操作之后,代码工作正常。
关于另一个问题,我在这里所做的关于从sql数据库收集数据的工作是最好的方法吗?我知道大多数人都遵循这个原则,但我也一直在研究数据集并将其绑定到控件,但我没有看到一篇文章说明什么样的实现方式更好/更快?
1条答案
按热度按时间mlnl4t2r1#
将用户界面代码与数据库代码分开是一种很好的做法。你的分离是非常好的,除了几个消息框,你从你的家庭显示
SqlControl
. 此功能不应与数据库代码混合使用。假设ui更改为web应用程序。反之亦然。ui不应该关心数据来自何处。它可能是火星上一个网络服务的本地计算机上的一个文本文件。我已经在
SQLContol
shared,这意味着调用代码不需要创建SQLControl
. 类与所有示例“共享”相同的数据。类唯一的数据是ConStr
所以这很好。连接和命令应该在使用它们的方法的本地。使用…end using块确保即使有错误也关闭并释放它们。dispose对于允许连接返回到连接池并释放非托管资源非常重要。
参数应包括
SqlDbType
以及Size
如适用。请参阅以下文章了解原因。http://www.dbdelta.com/addwithvalue-is-evil/ 以及https://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/ 还有一个:https://dba.stackexchange.com/questions/195937/addwithvalue-performance-and-plan-cache-implications 这是另一个https://andrevdm.blogspot.com/2010/12/parameterised-queriesdont-use.html通常id是整数。我就是这样设置代码的。如果它们确实是弦的话,你就必须改变它们。
你可能已经试着太过普通太快了。一旦您熟悉了sql server和vb.net,您可能需要重新组合一些代码以避免重复。
您没有显示
@@Identity
.ScopeIdentity
它的回报有点限制,所以你有更好的机会得到你期望的价值。与access不同,sqlserver可以在一条语句中执行多个命令。我添加了一个函数来演示。很抱歉,这些都没有经过测试,但我也做过很多次类似的测试。