vb.net - 如何解决 Visual Studio 中的数据集和数据库连接问题?
问题描述
我正在使用带有 MS Access 数据库的 VB.NET。有两个相互关联的表。
我按照以下步骤与数据集和绑定源建立数据库连接。
- 在数据源下添加新的数据源
- 数据库作为数据源类型
- 数据集作为数据库模型 >>
- 选择的数据连接
- 在数据库对象下,我选择了想要用于目的的表(s),比如客户表也点击了视图
- 然后完成。
- 现在在Data source,选择Dataset然后 Table of Customers并将详细信息和数据网格视图拖到表单并添加用于添加、删除更新记录的按钮。
- 现在运行应用程序。
运行应用程序后,它不会查看、添加、更新和删除数据库中的记录。
将记录添加到数据库的代码
CustomersBindingSource.AddNew()
将记录更新到数据库的代码
CustomersBindingSource.EndEdit()
CustomersTableAdapter.Update(SrsbdbDataSet.Customers)
从数据库中删除记录的代码
CustomersBindingSource.RemoveCurrent()
我还编辑了 app.config 文件中的连接字符串,以检查连接字符串问题,但对该问题没有用处。
请让我知道我在哪里做错了。
解决方案
客户BindingSource.AddNew()
这不会将记录添加到访问数据库,而是将记录添加到 BindingSource 的列表中,该列表(当在 BindingSource 上调用 EndEdit 时)YourDataSetName.Customers
作为新的 DataRow 被推入 DataTable - 如果您要查看所有行你会YourDataSetName.Customers
看到有一些(可能是从数据库下载的,当你启动应用程序时)并且它们的DataRowState为 Unchanged,然后是你添加的新的,DataRowState 为 Additional
尚未将任何内容保存到数据库中。此数据仅在数据集的数据表中,它是数据库表的客户端表示。它本身不是一个数据库表。与数据库表相比,它当然可以有更多或更少的列和不同的类型。它只是数据库数据的临时存储;您下载一些,添加一些,更改一些,删除一些,也许保存等。相关的 DataRow 跟踪您对其数据所做的所有这些事情,并记录它是否已添加/修改/删除/未更改等
TableAdapter 是在 DataTable 和数据库之间来回推送数据的东西
CustomersTableAdapter.Update()
当您想将数据保存到数据库时调用。以微软的名义命名它Update
是一个废话,因为它使人们认为它只执行 SQL UPDATE 查询;如果它被调用SaveChanges
(后来它被调用;EF 使用 SaveChanges)会更清楚.. 你只需要记住那个 - “更新意味着保存”
因此,您调用Update(datatable or dataset here)
并传入您的 DataTable 及其所有修改/删除/添加的行。TableAdapter 逐行扫描整个 DataTable,查看每一行的 DataRowState。如果已添加,则 TableAdapter 将调用其内置的 INSERT SQL 查询来保存该行。如果已修改,则执行 SQL UPDATE。已删除状态会导致 SQL DELETE。数据行知道下载的原始数据和现在的数据;这有时对于确定其他人是否在我们拥有它时保存了这一行至关重要,因此我们可以避免用我们的覆盖他们的更改
在此过程结束时,数据已保存,行状态已全部设置为未更改(因为数据库中的数据现在相同,不再需要保存行数据)。
当您编辑文件时,该过程的这一部分就像出现在文本编辑器选项卡上的小 * - 状态为“已添加/已修改/已删除”的数据行具有需要保存的未保存更改。保存后,状态恢复为未更改。我有没有提到 TableAdapter.Update 应该被称为 Save?
总而言之,保存的过程是要求编辑控件EndEdit()
然后要求相关的绑定源EndEdit
- 这确保我们有一个包含所有更改并准备保存的数据表,然后调用tableadapter.Update
. 当用户单击保存按钮时,用户输入的控件可能会在失去焦点时提交其编辑。但调用 endedit 可以确保。如果您不确定,请创建一个新表单,将 DataGridView 从 Data Sources 窗口中拖放到其上,然后查看 Save 按钮是如何连接的 - 从内存中它执行 Validate、几个 EndEdits 和一个 UpdateAll(TableAdapterManager,管理 TableAdapter,以正确的顺序对它们调用 Update 以确保父行在子行之前保存)
如果您开始进行更多修改,行状态将再次更改,但就像以前一样,将更改提交到数据库的是 TableAdapter.Update() 无论您进行了何种更改
最后要注意的是 Access 是一个基于文件的数据库。可能你有你的项目,例如:
C:\projects\accesswhatever\
你在你的桌面上有你的访问数据库:
c:\users\you\desktop\access.mdb
当您将访问数据库连接到事物时,VS 会出现一个冗长而冗长的对话框(没有人阅读;)),其中基本上说“我将把数据库放入您的项目中,然后将其复制到构建时的 bin 文件夹”。
因此,您单击“确定”而不考虑它的后果并进行构建。您的磁盘现在看起来像:
C:\users\you\desktop\access.mdb 'call it DB X
C:\projects\accesswhatever\access.mdb 'call it DB Y
C:\projects\accesswhatever\bin\debug\access.mdb 'call it DB Z
您正在运行的程序会将数据保存在最后一个 DB Z 中。每次构建时(如果您更改代码,每次单击播放时都可能发生这种情况),Visual Studio 将删除 Z 并将 Y 复制到 Z。
你现在真的很困惑;你的代码说它正在节省。您正在查看桌面上的 DB X 或项目库中的 DB Y,并且想知道这些数据到底在哪里?
它在 DB Z 中的bin\debug
文件夹中,在您的 app.exe 旁边 - 请记住,每次构建时,VS 都会擦除您更改的数据库并用一个干净的数据库替换它。如果要更改此设置,请单击解决方案资源管理器中的数据库并将“复制到输出”从“始终复制”设置为“如果较新则复制”。现在它只会在您进行架构更改时复制,所以.. 添加一个新表,然后 VS 将用一个新表擦除您精心策划的测试数据库.. 但它更像是好的,因为新的空数据库至少有没有你的程序将崩溃的额外表:)
推荐阅读
- python - Python 文本帮助大文件
- python - 如何在 BGR 图像中添加特定值的 Alpha 通道
- ios - 在 Objective C 代码中以视图的形式访问 Unity 3d UI 组件,例如 Panel/Image
- assembly - 中断处理程序的地址。我怎样才能获得它?
- android - Google 地点选择器立即关闭
- mapbox - 在静态 mapbox img 上计算 256px 瓦片的 lat long
- java - 如何从
- excel - VBA 获取网页链接并将文件下载到
- javascript - 如何通过组件内部的方法传递道具?
- c# - C# Selenium - 如何确定单选按钮是否被选中