需要从 VB.NET 内的数据库中检索基于 table 中的名称键的附加值
Need to retrieve additional values based on Name key in table from DB within VB.NET
所以最初我检索了我拥有的 table 中具有名称标识符的所有值,并将它们放入组合框中。加载到 table 中的数据是:
EstablishConnection("SELECT Name FROM Publishers")
我使用 table 适配器配置向导中的查询构建器创建了一个字符串查询
SELECT PubID, [Company Name], Address, City, State, Zip, Telephone, Fax
FROM Publishers
WHERE Name=''
并在 VB 中使用组合框的选定值实现它
EstablishConnection(String.Format("SELECT PubID, [Company Name], Address, City, State, Zip, Telephone, Fax FROM Publishers WHERE Name='{0}'", oleDbCmbNames.SelectedItem.ToString()))
但是,它只有 returns 一个值,而不是全部,并且根据我给它的异常说数据库丢失了。
Public Class Form1
Private Sub PublishersBindingNavigatorSaveItem_Click(sender As Object, e As EventArgs)
Me.Validate()
Me.PublishersBindingSource.EndEdit()
Me.TableAdapterManager.UpdateAll(Me.ContactsDataSet)
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'TODO: This line of code loads data into the 'ContactsDataSet.Publishers' table. You can move, or remove it, as needed.
Me.PublishersTableAdapter.Fill(Me.ContactsDataSet.Publishers)
'TODO: This line of code loads data into the 'ContactsDataSet.Publishers' table. You can move, or remove it, as needed.
Me.PublishersTableAdapter.Fill(Me.ContactsDataSet.Publishers)
'Establish a connection to the DB and fill combobox with names
EstablishConnection("SELECT Name FROM Publishers")
End Sub
' Instantiate Connection
Dim connection As OleDb.OleDbConnection
' This function prepares, establishs, inquires, and closes the connection to the DB
Public Sub EstablishConnection(request As String)
Try
' Initialize new connection
connection = New OleDb.OleDbConnection
' Initialize SQL inquiry
Dim command As New OleDb.OleDbCommand()
' Assign Inquiry request to command
command = New OleDb.OleDbCommand(request, connection)
' Assign db source before establishing a connection
connection.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Contacts.mdb"
' Open connection
connection.Open()
' Initialize DB reader with inquiry
Dim oleDBReader As OleDb.OleDbDataReader = command.ExecuteReader
If oleDbCmbNames.Items.Count = 0 Then
' Read db, return inquries
While oleDBReader.Read
' Add each inquiry name string to combobox
oleDbCmbNames.Items.Add(oleDBReader("Name").ToString)
End While
ElseIf oleDbCmbNames.Items.Count > 0 Then
' Read db, return inquries
While oleDBReader.Read()
PubIDLabelTextResult.Text = oleDBReader.Item("PubID").ToString
Company_NameLabelTextResult.Text = oleDBReader.Item("[Company Name]").ToString
AddressLabelTextResult.Text = oleDBReader.Item("Address").ToString
CityLabelTextResult.Text = oleDBReader.Item("City").ToString
StateLabelTextResult.Text = oleDBReader.Item("State").ToString
ZipLabelTextResult.Text = oleDBReader.Item("Zip").ToString
TelephoneLabelTextResult.Text = oleDBReader.Item("Telephone").ToString
FaxLabelTextResult.Text = oleDBReader.Item("Fax").ToString
End While
End If
Catch ex As Exception
' Return if db not found or cannot connect.
MessageBox.Show("Could not connect to DB. Ensure DB is not missing.")
Finally
' Close connection
connection.Close()
End Try
End Sub
Private Sub oleDbCmbNames_SelectedIndexChanged(sender As Object, e As EventArgs) Handles oleDbCmbNames.SelectedIndexChanged
EstablishConnection(String.Format("SELECT PubID, [Company Name], Address, City, State, Zip, Telephone, Fax FROM Publishers WHERE Name='{0}'", oleDbCmbNames.SelectedItem.ToString().Trim))
End Sub
End Class
因此,对于我在评论中提出的问题,我假设您想将组合框用作导航设备。您更改了组合框,并且表单上的许多其他控件也改变了它们内容。我假设这是从代码试图做的事情来看的。如果这不是您想要做的,请告诉我,我会修改答案
所以你有一个数据集和一个 table 加载你所有发布者的适配器。两次,实际上 - 您可以从表单 Load 事件处理程序中删除其中一个相同的填充命令。没有必要紧接着对同一件事进行两次调用
接下来,您需要丢弃 EstablishConnection 中的所有代码,以及对它的每次调用。一起使用数据适配器和 table 适配器,尤其是当您刚开始使用时,会导致混淆。 Tableadapters 很棒,它们生成安全的 sql 可以包含参数并且易于使用。你在 EstablishConnection sub 中的内容是 运行 SQL 的一种非常不安全的方式。为什么,请阅读 http://bobby-tables.com 然后回来删除该代码,这样你就拥有了这个:
Public Class Form1
Private Sub PublishersBindingNavigatorSaveItem_Click(sender As Object, e As EventArgs)
Me.Validate()
Me.PublishersBindingSource.EndEdit()
Me.TableAdapterManager.UpdateAll(Me.ContactsDataSet)
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.PublishersTableAdapter.Fill(Me.ContactsDataSet.Publishers)
End Sub
End Class
是的,您后面的表单代码现在需要包含的所有代码
现在,转到表单设计器并删除与发布者相关的所有组合、文本框、标签等。我知道这听起来像是我想让你扔掉你的项目,但这是为了让我能达到一致的状态,我们在同一页面上,我知道你的表格上有什么以及它是如何连接的。
清除表单后(您可以将 ContactsDataSet、PublisherTableAdapter 和其他内容留在底部,加上与发布者无关的任何控件)打开“查看”菜单,转到“其他”Windows 并选择“数据源” .它会显示一个像这样的工具面板(这是一张很棒的图片,因为它也演示了其他一些要点):
(credit)
因为,从上面的代码来看,在我看来,您想将发布者的详细信息加载到标签而不是文本框中,您可以展开联系人数据集,展开发布者节点并更改其下节点的类型(地址、邮编、phone、传真等)从文本框到标签。将它们更改为标签后,将它们一一拖放到表单上。或者,将 header 节点从 DatagridView 更改为 Details,然后将 header 节点拖到窗体上,以快速为 header 节点
下的每个内容创建一个标签
您现在有一堆数据绑定(连接)到您的联系人数据集发布者的标签 table。您可以单击任何标签并在属性网格的(数据绑定)行中查看它们的文本 属性 连接到发布者 table 的列,并且它们的数据源是称为 publishersBindingSource 的东西.绑定源在多个记录的列表中维护“当前记录”的概念。你有 100 个发布者,你将 bindingsource 的当前记录设置为第 50 个,所有标签显示第 50 个发布者的数据。您告诉绑定源移动到第 51 个发布者,所有标签都会自动更改其内容。您可以通过 运行 您的项目并单击表单顶部绑定导航器中的箭头来查看实际效果。调用 Fill in the form load loaded 100 publishers(比方说),bindingsource 开始指向第一个,单击 next/prev/last 或输入一个数字将更改位于 100 个列表之间的 bindingsource 的当前记录数据集中的发布者,以及您的控件(一次只能显示一个发布者)
现在,我们在表单中添加一个组合作为导航器:
- 向您的表单添加组合
- 在属性 window 中将其数据源设置为 PublishersBindingSource - 这很重要
- 在 DisplayMember 设置中输入单词 Name - 需要组合才能显示正确的内容
- 将 DropDownStyle 设置为 DropDownList - 可选但 editable 组合在这种情况下确实令人困惑
运行 你的项目
当这样配置时,组合将显示它在绑定源中找到的项目列表,当前选择的项目将驱动绑定源的当前记录。更改组合中的选定项目将导致所有标签更改,因为组合影响了绑定源的当前记录。该组合不需要任何其他东西来充当导航器,实际上尝试绑定其他东西会导致它开始像当前记录中的数据编辑器一样工作,而不是所有记录的导航器
所以最初我检索了我拥有的 table 中具有名称标识符的所有值,并将它们放入组合框中。加载到 table 中的数据是:
EstablishConnection("SELECT Name FROM Publishers")
我使用 table 适配器配置向导中的查询构建器创建了一个字符串查询
SELECT PubID, [Company Name], Address, City, State, Zip, Telephone, Fax
FROM Publishers
WHERE Name=''
并在 VB 中使用组合框的选定值实现它
EstablishConnection(String.Format("SELECT PubID, [Company Name], Address, City, State, Zip, Telephone, Fax FROM Publishers WHERE Name='{0}'", oleDbCmbNames.SelectedItem.ToString()))
但是,它只有 returns 一个值,而不是全部,并且根据我给它的异常说数据库丢失了。
Public Class Form1
Private Sub PublishersBindingNavigatorSaveItem_Click(sender As Object, e As EventArgs)
Me.Validate()
Me.PublishersBindingSource.EndEdit()
Me.TableAdapterManager.UpdateAll(Me.ContactsDataSet)
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'TODO: This line of code loads data into the 'ContactsDataSet.Publishers' table. You can move, or remove it, as needed.
Me.PublishersTableAdapter.Fill(Me.ContactsDataSet.Publishers)
'TODO: This line of code loads data into the 'ContactsDataSet.Publishers' table. You can move, or remove it, as needed.
Me.PublishersTableAdapter.Fill(Me.ContactsDataSet.Publishers)
'Establish a connection to the DB and fill combobox with names
EstablishConnection("SELECT Name FROM Publishers")
End Sub
' Instantiate Connection
Dim connection As OleDb.OleDbConnection
' This function prepares, establishs, inquires, and closes the connection to the DB
Public Sub EstablishConnection(request As String)
Try
' Initialize new connection
connection = New OleDb.OleDbConnection
' Initialize SQL inquiry
Dim command As New OleDb.OleDbCommand()
' Assign Inquiry request to command
command = New OleDb.OleDbCommand(request, connection)
' Assign db source before establishing a connection
connection.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Contacts.mdb"
' Open connection
connection.Open()
' Initialize DB reader with inquiry
Dim oleDBReader As OleDb.OleDbDataReader = command.ExecuteReader
If oleDbCmbNames.Items.Count = 0 Then
' Read db, return inquries
While oleDBReader.Read
' Add each inquiry name string to combobox
oleDbCmbNames.Items.Add(oleDBReader("Name").ToString)
End While
ElseIf oleDbCmbNames.Items.Count > 0 Then
' Read db, return inquries
While oleDBReader.Read()
PubIDLabelTextResult.Text = oleDBReader.Item("PubID").ToString
Company_NameLabelTextResult.Text = oleDBReader.Item("[Company Name]").ToString
AddressLabelTextResult.Text = oleDBReader.Item("Address").ToString
CityLabelTextResult.Text = oleDBReader.Item("City").ToString
StateLabelTextResult.Text = oleDBReader.Item("State").ToString
ZipLabelTextResult.Text = oleDBReader.Item("Zip").ToString
TelephoneLabelTextResult.Text = oleDBReader.Item("Telephone").ToString
FaxLabelTextResult.Text = oleDBReader.Item("Fax").ToString
End While
End If
Catch ex As Exception
' Return if db not found or cannot connect.
MessageBox.Show("Could not connect to DB. Ensure DB is not missing.")
Finally
' Close connection
connection.Close()
End Try
End Sub
Private Sub oleDbCmbNames_SelectedIndexChanged(sender As Object, e As EventArgs) Handles oleDbCmbNames.SelectedIndexChanged
EstablishConnection(String.Format("SELECT PubID, [Company Name], Address, City, State, Zip, Telephone, Fax FROM Publishers WHERE Name='{0}'", oleDbCmbNames.SelectedItem.ToString().Trim))
End Sub
End Class
因此,对于我在评论中提出的问题,我假设您想将组合框用作导航设备。您更改了组合框,并且表单上的许多其他控件也改变了它们内容。我假设这是从代码试图做的事情来看的。如果这不是您想要做的,请告诉我,我会修改答案
所以你有一个数据集和一个 table 加载你所有发布者的适配器。两次,实际上 - 您可以从表单 Load 事件处理程序中删除其中一个相同的填充命令。没有必要紧接着对同一件事进行两次调用
接下来,您需要丢弃 EstablishConnection 中的所有代码,以及对它的每次调用。一起使用数据适配器和 table 适配器,尤其是当您刚开始使用时,会导致混淆。 Tableadapters 很棒,它们生成安全的 sql 可以包含参数并且易于使用。你在 EstablishConnection sub 中的内容是 运行 SQL 的一种非常不安全的方式。为什么,请阅读 http://bobby-tables.com 然后回来删除该代码,这样你就拥有了这个:
Public Class Form1
Private Sub PublishersBindingNavigatorSaveItem_Click(sender As Object, e As EventArgs)
Me.Validate()
Me.PublishersBindingSource.EndEdit()
Me.TableAdapterManager.UpdateAll(Me.ContactsDataSet)
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.PublishersTableAdapter.Fill(Me.ContactsDataSet.Publishers)
End Sub
End Class
是的,您后面的表单代码现在需要包含的所有代码
现在,转到表单设计器并删除与发布者相关的所有组合、文本框、标签等。我知道这听起来像是我想让你扔掉你的项目,但这是为了让我能达到一致的状态,我们在同一页面上,我知道你的表格上有什么以及它是如何连接的。
清除表单后(您可以将 ContactsDataSet、PublisherTableAdapter 和其他内容留在底部,加上与发布者无关的任何控件)打开“查看”菜单,转到“其他”Windows 并选择“数据源” .它会显示一个像这样的工具面板(这是一张很棒的图片,因为它也演示了其他一些要点):
因为,从上面的代码来看,在我看来,您想将发布者的详细信息加载到标签而不是文本框中,您可以展开联系人数据集,展开发布者节点并更改其下节点的类型(地址、邮编、phone、传真等)从文本框到标签。将它们更改为标签后,将它们一一拖放到表单上。或者,将 header 节点从 DatagridView 更改为 Details,然后将 header 节点拖到窗体上,以快速为 header 节点
下的每个内容创建一个标签您现在有一堆数据绑定(连接)到您的联系人数据集发布者的标签 table。您可以单击任何标签并在属性网格的(数据绑定)行中查看它们的文本 属性 连接到发布者 table 的列,并且它们的数据源是称为 publishersBindingSource 的东西.绑定源在多个记录的列表中维护“当前记录”的概念。你有 100 个发布者,你将 bindingsource 的当前记录设置为第 50 个,所有标签显示第 50 个发布者的数据。您告诉绑定源移动到第 51 个发布者,所有标签都会自动更改其内容。您可以通过 运行 您的项目并单击表单顶部绑定导航器中的箭头来查看实际效果。调用 Fill in the form load loaded 100 publishers(比方说),bindingsource 开始指向第一个,单击 next/prev/last 或输入一个数字将更改位于 100 个列表之间的 bindingsource 的当前记录数据集中的发布者,以及您的控件(一次只能显示一个发布者)
现在,我们在表单中添加一个组合作为导航器:
- 向您的表单添加组合
- 在属性 window 中将其数据源设置为 PublishersBindingSource - 这很重要
- 在 DisplayMember 设置中输入单词 Name - 需要组合才能显示正确的内容
- 将 DropDownStyle 设置为 DropDownList - 可选但 editable 组合在这种情况下确实令人困惑
运行 你的项目
当这样配置时,组合将显示它在绑定源中找到的项目列表,当前选择的项目将驱动绑定源的当前记录。更改组合中的选定项目将导致所有标签更改,因为组合影响了绑定源的当前记录。该组合不需要任何其他东西来充当导航器,实际上尝试绑定其他东西会导致它开始像当前记录中的数据编辑器一样工作,而不是所有记录的导航器