如何使用BindingSource插入SQL Server



我想用Windows窗体和VB.中的BindingSource从SQL Server插入数据库

现在,我有一个DataTable,它的DataTableAdapter处于"详细信息"模式,还有一堆TextBox(和其他控件,但这不是问题所在),它们的Text属性绑定到我的BindingSource。

如果我填充TableAdapterXDataTableAdapter.Fill(XDataSet.XTable),那么这些TextBox从第一个条目接收数据,BindingSource具有数据库中的每一行和每一列的值,因此BindingSource和适配器可以工作。

我不想修改现有的条目,而是插入一个新条目,其内容与各种TextBox中链接的内容相同。

有人告诉我应该使用XBindingSource.AddNew(),最后,一旦我确定了TextBoxsXDataTableAdapter.Update(XDataSet.XTable)中的数据。

问题是,在我执行AddNew之前,我的BindingSource可以读取正在编写的内容。但是,一旦我到达AddNew,BindingSource的计数将以1递增,但无论TextBox的内容如何,其当前行的Items都是空的。

因此,问题是,在BindingSource.AddNew之后,数据库中的行正确地包含其值,但当前的新行为空,而不读取文本框的绑定源。BindingSource是否有任何指令要执行,以便它知道新行应该读取文本框?

因此,当我到达Update指令时,新行是空的,所以它不会更改任何内容。

我的问题是,如何告诉BindingSource当前新行就是TextBox中正在写入的内容。

我只想直接从控件绑定插入数据库,而不必手动链接每个控件。

如果可以的话,我会纠正一些误解;希望它能帮助你了解发生了什么:

现在我有一个DataTable,它的DataTableAdapter处于"详细信息"模式,还有一堆TextBox(和其他控件,但这不是问题),它们的Text属性绑定到我的BindingSource。

您有一个TableAdapter,这是VS在使用这种访问数据库的方法时为您生成的东西类型的通用名称。一定要称它们为TableAdapters,因为这就是我们对它们的了解,它们与DataAdapters不同,DataAdapters是访问数据库的更基本的东西。如果你称之为DataTableAdapter ,人们可能会混淆你的意思

TableAdapters没有";细节";模式"细节";指的是您在"数据源"窗口中所做的事情-您从数据网格更改为详细信息,然后将代表的数据表的节点拖到表单上,出现了一堆文本框等,还有一个表适配器、数据集、绑定源、绑定导航器,也许还有一个表格适配器管理器。在这一点上,除了运行程序,你什么也做不了,它将能够保存新的数据"细节";是指";创建一堆文本框而不是数据网格";并且是仅数据源窗口的函数

如果我填充TableAdapter XDataTableAdapter.fill(XDataSet.XTable),那么这些TextBox从第一个条目接收数据,BindingSource具有数据库中的每一行和每一列的值,因此BindingSource和适配器可以工作。

再一次,一个稍微的术语调整:你不填充TableAdapter,TableAdapter是一个填充数据表的设备。它填充的数据表位于数据集中。bindingsource被绑定(连接)到数据表。数据表保存从数据库下载的本地数据的缓存。文本框已绑定到绑定源。因为一个文本框一次只能显示一条记录,所以bindingsource维护了什么是"记录"的知识;当前";记录bindingnavigator(工具栏)移动bindingsource的当前指针,从而导致文本框更改值。您可以使用文本框来更改值或添加新值。这导致bindingsource将更改传输到底层数据表,影响它认为是";当前";一行在某个时刻,您将更改后的数据表保存回数据库。底层数据表行从Unchanged(下载时的状态)更改为Modified。这就是表适配器知道如何运行SQLUPDATE查询的方式——它查看行的状态

我不想修改现有条目,而是插入一个新条目,其内容与各种TextBox中链接的内容相同。有人告诉我应该使用XBindingSource.AddNew(),最后,一旦我确定了TextBoxs XDataTableAdapter.Update(XDataSet.XTable).中的数据

你确实可以做到这一点。bindingnavigator上有一个+按钮来执行此操作,或者您可以编写一些其他代码来调用bindingsource上的AddNew()。当您调用AddNew时,bindingsource会生成一个新的数据行,但不会立即向数据表中添加任何内容。当您将bindingsource告知AddNew时,它将切换为将其当前项指向新项,所有文本框都为空,您可以在其中键入新的详细信息。这些细节将进入新的临时行,但请记住,该行还不是底层数据表的一部分

问题是,在执行AddNew之前,我的BindingSource可以读取正在编写的内容。但是,一旦我到达AddNew,BindingSource的计数将以1递增,但无论TextBox的内容如何,其当前行的Items都是空的。

这不是问题,这是设计的。这和打开Word并编写文档是一样的——它还没有保存在硬盘上,只是在内存中。您需要做一些事情将其提交到硬盘,就像您需要对绑定源做一些事情使其将新项目提交到底层数据存储(数据表)一样

要使其提交,您需要执行以下操作:导航到另一条记录,或在bindingsource上调用EndEdit()。此时,它将该行添加到基础表中,并且该新行的RowState为Added——这意味着当表适配器运行其Update(实际上应该称为Save)时,它将使用内置的SQL INSERT查询来保存该行;因为它已添加/新增/需要插入数据库

因此,问题是,在BindingSource.AddNew之后,数据库中的行正确地包含其值,但当前的新行为空,而不读取文本框的绑定源。BindingSource是否有任何指令要执行,以便它知道新行应该读取文本框?

我认为你做事的顺序不对。你应该添加新数据,然后用新数据填充文本框,然后做一些事情,比如导航离开新数据,或者点击保存或其他对表单/绑定源执行Validate()/EndEdit()的按钮。新行的提交发生在bindingsource的EndEdit()上;这将该行放入表中,但此时仍未将其保存到数据库中。要保存,必须调用tableadapter.Update(theTable)

这可能看起来有点奇怪,但还是要把它想象成MS Word。您可以打开一个现有的文档,然后对一个新文档执行Ctrl+N,然后编写文档。新文档尚未保存到磁盘。

在表适配器方面,过程是相同的:您可以下载一个现有的数据库表,然后为新行执行AddNew,然后编写新行的详细信息。新行尚未保存到数据库中。