mysql - 如何使用 DataRow 更新数据库?

标签 mysql .net vb.net datatable datarow

首先,我在全局创建了 DataSet 和 MySQLDataAdapter。然后在 Form_Load 事件中,我像这样查询我的所有表。

        dS = New DataSet
        dA = New MySqlDataAdapter(myCommand)
        Using sqlConn As New MySqlConnection(connStr)
            myCommand = New MySqlCommand("Select ID, DevCompanyName from developer_name_table; Select ID, DevType from development_type_table; Select ID, Mukim from mukim_table; Select ID, Daerah from daerah_table; Select ID, Negeri from negeri_table; Select * from project_record ORDER BY FloatNo desc limit 1", sqlConn)
            sqlConn.Open()
            MsgBox("Connection open.")
            Dim myCB As New MySqlCommandBuilder(dA)

            dA.SelectCommand = myCommand
            dA.UpdateCommand = myCB.GetUpdateCommand
            dA.InsertCommand = myCB.GetInsertCommand
            dA.DeleteCommand = myCB.GetDeleteCommand

            dA.Fill(dS)
            dA.FillSchema(dS, SchemaType.Source)
            dS.Tables(0).TableName = "developer_name_table"
            dS.Tables(1).TableName = "development_type_table"
            dS.Tables(2).TableName = "mukim_table"
            dS.Tables(3).TableName = "daerah_table"
            dS.Tables(4).TableName = "negeri_table"
            dS.Tables(5).TableName = "project_record"
        End Using

一切正常,直到我尝试像这样将新记录添加到数据库中。下面的添加记录代码在一个按钮点击事件下。首先我检查记录是否存在,然后像这样添加一个新行。

        For Each r As DataRow In dS.Tables("project_record").Rows()
            If r.Item("FloatNo") = TextBox1.Text.Trim() Then
                MsgBox("Project exist. Please recheck.")
                Exit Sub
            End If
        Next
        SecurityAdd() 'This is just to fill None if field are empty.
        Dim row = dS.Tables("project_record").NewRow()
        row.Item("FloatNo") = TextBox1.Text.Trim()
        row.Item("DevCompanyName") = ComboBox1.Text.Trim()
        row.Item("DevType") = ComboBox2.Text.Trim()
        row.Item("LotPt") = TextBox2.Text.Trim()
        row.Item("Mukim") = ComboBox3.Text.Trim()
        row.Item("Daerah") = ComboBox4.Text.Trim()
        row.Item("Negeri") = ComboBox5.Text.Trim()
        row.Item("TempReference") = RichTextBox1.Text.Trim()
        row.Item("PermanentNo") = 0
        row.Item("QuotationNo") = 0
        row.Item("InvoiceNo") = 0
        row.Item("Staff") = loggedUser.ToString() 'Just user ID.
        dS.Tables("project_record").Rows.Add(row)
        dA.Update(dS, "project_record")

更新后,我确定数据集已更新,因为我第二次单击添加记录时,消息框告诉我该记录已存在。但是当我检查我的数据库时,没有新记录?我在这里做错了什么?

最佳答案

问题是您正在尝试配置 DataAdapter 以处理 DataSet 中的所有 6 个表。如果查看构建的 INSERT 或 UPDATE 命令,您会发现它们是所有表中所有列的混合体。设置一个 DataAdapter 来为您完成繁重的工作,只需一张表即可。

我不知道 negeri 和其他翻译成什么,但它看起来只有一个是事务表;其余的,如 DevCompanyName 似乎是为项目记录表提供值的域/代码表。

通常,其中一些是根据业务规则固定的,那些不需要添加/更新的方法。其他人可能很需要一种方法来添加新项目,但只是偶尔。手动执行这些更新,以便可以设置 DA 并将其与应用程序关注的主表一起使用。如果有用于添加 Mukim 等人的表单或选项卡,只需在那里插入并刷新即可。

至少,我会将这些域表存储在一个单独的 DataSet 中,这样它们就不会碍事,但是只使用一个,您可以像这样配置它:

Using dbcon As New MySqlConnection(MySQLConnStr)

        dsS = New DataSet
        dbcon.Open()

        ' add table 1 - Mukim
        dsS.Tables.Add("Mukim")
        Using cmd As New MySqlCommand("SELECT DeptCode, Descr FROM Department", dbcon)
            dsS.Tables("Mukim").Load(cmd.ExecuteReader())
            cboColors.DataSource = dsS.Tables("Mukim")
            cboColors.DisplayMember = "Descr"    ' ie "Management"
            cboColors.ValueMember = "DeptCode"   ' eg "MGMT"
        End Using

        ' add table 2 - negeri
        ' this table is fixed - new rows are very rare
        Using cmd As New MySqlCommand("SELECT DeptCode, Descr FROM cDepartment", dbcon)
            Dim dt As New DataTable
            dt.Load(cmd.ExecuteReader)
            cboDept.DataSource = dt
            cboDept.DisplayMember = "Descr"             ' "Sommelier"
            cboDept.ValueMember = "DeptCode"            ' "SOMM"
        End Using

        ' etc

        ' main transaction table - project
        ' do this last
        Dim prjcmd = New MySqlCommand(prjSql, dbcon)
        daSample = New MySqlDataAdapter(prjcmd)

        Dim cb As New MySqlCommandBuilder(daSample)
        daSample.SelectCommand = prjcmd
        daSample.InsertCommand = cb.GetInsertCommand
        ' etc

        dsS.Tables.Add("Project")
        daSample.Fill(dsS.Tables("Project"))
        daSample.FillSchema(dsS.Tables("Project"), SchemaType.Source)
    End Using

代码将这些域/代码表存储在 DataSet 中,以备可能更改的那些域/代码表。它们不是适配器,而是使用 DataReader 填充的。任何固定的,例如“部门”,都会发布到相关的 CBO 并被遗忘。根据每个实际更新的频率,您可以对所有这些方法使用此方法,并在它们获得新行时绑定(bind)到一个新表。

该代码还使用作为相关 CBO 的 DataSource 创建的 DataTable。我不确定您的代码在做什么,因为它存储了 Combobox.Text。如果我用新条目更新 DataTable,它可以被编码为自动显示。

结果是 DataAdapter 知道如何更新主 Project 表等,并且不会被这些其他表混淆。然后插入就和你拥有的差不多了:

    Dim dr = dsS.Tables("Project").NewRow
    dr("Name") = "My New Row"
    dr("Mukim") = cboMukim.SelectedValue     ' MGMT
    ... etc
    dsS.Tables(1).Rows.Add(dr)

    daSample.Update(dsS.Tables("Project"))
    dsS.Tables("Project").AcceptChanges()

    ' See Notes
    Dim rows = daSample.Fill(dsS.Tables("Project"))       ' refresh
    dsS.Tables("Project").Rows.Remove(dr)
  1. 由于 Mukim CBO 现在已绑定(bind),因此使用 SelectedValue 存储到项目中。
  2. DataTable 跟踪哪些行是新的、添加的、删除的等。更新后,使用 AcceptChanges 清除这些标志。
  3. 在表使用 AI PK 的情况下,新行最初将为 0。如果刷新项目表,您将获得一条记录,其中包含数据库提供的 PK。这意味着“我的新行”会有 2 条记录,一 strip 有实际数据库提供的 ID,一条为零。删除(不是删除!)我们添加的新行消除了这一点。

不清楚第 3 项是否适用。 FloatNo 可能是 PK,在这种情况下您可以跳过删除。此外,循环遍历“所有”行以查看“FloatNo”是否存在只会循环遍历加载的一 (1) 行,因为查询包含 LIMTI 1 子句。

并非毫无意义,但您可以通过使用 DataGridView 来简化 UI。 Mukim 等人不是表单上的组合框,而是 ComboBox 列,以便为您向表中添加新行。您只需要在验证和/或他们点击保存后进行更新。

关于mysql - 如何使用 DataRow 更新数据库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37991293/

相关文章:

php - Joomla:从模型中调用辅助函数?

mysql - 如何上传新的 Mysql 数据库表?

c# - Nustache View 引擎 ArrayTypeMismatchException

vb.net - List.add 覆盖列表中以前的项目 VB.NET

mysql - 刷新数据库中早于 X 天的每个条目

MySQL和Hibernate同时读写

c# - 如何使 C# 应用程序充当服务?

.net - 立即执行 LINQ 查询的最便宜的方法是什么

mysql - Insert语句向数据库添加数据

vb.net - 检查文件名的一部分是否存在