【问题标题】:Updating Database never works on first time, have to do it twice?更新数据库永远不会在第一次工作,必须做两次?
【发布时间】:2021-12-04 21:36:19
【问题描述】:

我正在尝试使用用户可以编辑/插入行/删除行的 DataGridView 更新/编辑数据库。一切似乎都可以单击“插入”或“更新”链接单元格。他们总是在第一次点击时失败(它没有给出详细的错误)并且总是在第二次点击时工作。

我看不到点击一次或两次之间发生了什么变化。

将数据加载到 DATAGRIDVIEW:

private void loadDB()
        {
            try
            {
                string connstring = string.Format("Server={0}; database={1}; UID={2}; password={3}",
                dbUtil.creds.server, dbUtil.creds.database, dbUtil.creds.username, dbUtil.creds.password);

                conn = new MySqlConnection(connstring);

                // since we have multiple tables we cant load data on form load
                // so we cant open conn there either. do it here, only once, the first time.
                onlyOnce();

                adapter = new MySqlDataAdapter("SELECT *, 'Delete' AS 'Delete' FROM RIS" + tableShown, conn);
                builder = new MySqlCommandBuilder(adapter);

                adapter.InsertCommand = builder.GetInsertCommand();
                adapter.UpdateCommand = builder.GetUpdateCommand();
                adapter.DeleteCommand = builder.GetDeleteCommand();

                ds = new DataSet();
                adapter.Fill(ds, "RIS" + tableShown);
                dbView.DataSource = null;
                dbView.DataSource = ds.Tables["RIS" + tableShown];

                for (int i = 0; i < dbView.Rows.Count; i++)
                {
                    DataGridViewLinkCell linkCell = new DataGridViewLinkCell();
                    dbView[dbView.Columns.Count - 1, i] = linkCell;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            cellCount = dbView.Columns.Count - 1;
        }

如果用户添加了行,则更新单元格:

        private void dbView_UserAddedRow(object sender, DataGridViewRowEventArgs e)
        {
            int lastRow = dbView.Rows.Count - 2;
            DataGridViewRow nRow = dbView.Rows[lastRow];
            DataGridViewLinkCell linkCell = new DataGridViewLinkCell();
            dbView[cellCount, lastRow] = linkCell;
            nRow.Cells["Delete"].Value = "Insert";
        }

如果用户更改了现有行中的单元格,则更新单元格:

        private void dbView_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                int lastRow = e.RowIndex;
                DataGridViewRow nRow = dbView.Rows[lastRow];
                DataGridViewLinkCell linkCell = new DataGridViewLinkCell();
                dbView[cellCount, lastRow] = linkCell;
                if (dbView.Rows[e.RowIndex].Cells[cellCount].Value.ToString() == "Delete")
                {
                    nRow.Cells["Delete"].Value = "Update";
                }
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }
        }

取决于单元格值,更新/插入/或删除行:

 private void dbView_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            string database = "RIS" + tableShown;
            int result = 0;
            try
            {
                if (e.ColumnIndex == cellCount)
                {
                    string Task = dbView.Rows[e.RowIndex].Cells[cellCount].Value.ToString();
                    if (Task == "Delete")
                    {
                        if (MessageBox.Show("Are you sure to delete?", "Deleting...", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                        {
                            int ThisRow = e.RowIndex;
                            dbView.Rows.RemoveAt(ThisRow);
                            ds.Tables[database].Rows[ThisRow].Delete();
                            result = adapter.Update(ds, database);
                        }
                    }
                    else if (Task == "Insert")
                    {
                        int lastRow = dbView.Rows.Count - 2;
                        DataRow dr = ds.Tables[database].NewRow();
                        foreach (DataGridViewColumn col in dbView.Columns)
                        {
                            if (col.HeaderText != "Delete")
                            {
                                dr[col.HeaderText] = dbView.Rows[lastRow].Cells[col.HeaderText].Value;
                            }
                        }
                        ds.Tables[database].Rows.Add(dr);
                        ds.Tables[database].Rows.RemoveAt(ds.Tables[database].Rows.Count - 1);
                        dbView.Rows.RemoveAt(dbView.Rows.Count - 2);
                        dbView.Rows[e.RowIndex].Cells[cellCount].Value = "Delete";
                        result = adapter.Update(ds, database);
                    }
                    else if (Task == "Update")
                    {
                        int thisRow = e.RowIndex;
                        foreach (DataGridViewColumn col in dbView.Columns)
                        {
                            if (col.HeaderText != "Delete")
                            {
                                ds.Tables[database].Rows[thisRow][col.HeaderText] = dbView.Rows[thisRow].Cells[col.HeaderText].Value;
                            }
                        }
                        result = adapter.Update(ds, database);
                        dbView.Rows[e.RowIndex].Cells[cellCount].Value = "Delete";
                    }
                }
            }
            catch (Exception ex) { }
            // reload data to clear ds and dt after success
            if(result > 0)
            {
                loadDB();
            }
        }

任何想法为什么链接单元在第一次点击时失败但第二次没有?

【问题讨论】:

  • 第一次失败是什么意思?有没有例外?
  • 设法获得更详细的异常:[无法将数据写入传输连接。现有连接被远程主机强行关闭。]
  • 已尝试将 POOLING 设置为 false 和 true,两者都没有区别。
  • 我不知道你为什么要为此烦恼。数据表已经以添加/更新/删除方式跟踪对其行所做的更改。你在这里不必要地重新发明了一个轮子
  • 不,数据集跟踪更改,然后必须将其更新到远程 MySql 服务器。这是做什么的......

标签: c# mysql datagridview sql-update sql-insert


【解决方案1】:

对于任何可能遇到类似错误的人,这里有一种更优雅的方法(没有错误)。

        private void loadDB()
        {
            
                string connstring = string.Format("Server={0}; database={1}; UID={2}; password={3};",
                dbUtil.creds.server, dbUtil.creds.database, dbUtil.creds.username, dbUtil.creds.password);

                conn = new MySqlConnection(connstring);

            if (this.OpenConnection() == true)
            {
                adapter = new MySqlDataAdapter("select * from RIS" + tableShown, conn);
                DataSet DS = new DataSet();
                adapter.Fill(DS);
                dbView.DataSource = DS.Tables[0];

                //close connection
                this.CloseConnection();
            }
        }

        private bool OpenConnection()
        {
            try
            {
                conn.Open();
                return true;
            }
            catch (MySqlException ex)
            {
                //When handling errors, you can your application's response based on the error number.
                //The two most common error numbers when connecting are as follows:
                //0: Cannot connect to server.
                //1045: Invalid user name and/or password.
                switch (ex.Number)
                {
                    case 0:
                        MessageBox.Show("Cannot connect to server. Contact administrator");
                        break;
                    case 1045:
                        MessageBox.Show("Invalid username/password, please try again");
                        break;
                    default:
                        MessageBox.Show(ex.Message);
                        break;
                }
                return false;
            }
        }

        private bool CloseConnection()
        {
            try
            {
                conn.Close();
                return true;
            }
            catch (MySqlException ex)
            {
                MessageBox.Show(ex.Message);
                return false;
            }
        }

        private void dbView_RowValidated(object sender, DataGridViewCellEventArgs e)
        {
            DataTable changes = ((DataTable)dbView.DataSource).GetChanges();

            if (changes != null)
            {
                MySqlCommandBuilder mcb = new MySqlCommandBuilder(adapter);
                adapter.UpdateCommand = mcb.GetUpdateCommand();
                adapter.Update(changes);
                ((DataTable)dbView.DataSource).AcceptChanges();
            }
        }

【讨论】:

    猜你喜欢
    • 2019-04-29
    • 1970-01-01
    • 1970-01-01
    • 2012-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-18
    • 1970-01-01
    相关资源
    最近更新 更多