DataGridView編輯后立即更新到數據庫的兩種方法


  DataGridView控件是微軟預先寫好的一個顯示數據的控件,功能非常強大,可以顯示來自數據庫表的數據和XML等其他來源的數據。最近在做一個迷你超市管理系統,要大量用到這個控件。所以花時間好好研究了下。

這是迷你超市管理系的庫存數據DataGridView,用戶一定會想如果能直接在DGV中修改數據就好了。

是的,這是一個很好的想法,這個功能微軟早就幫我們想到了,現在可以使兩種方法加以實現。下面就來介紹一下他們。

第一張方法:基於DataAdapter對象創建一個CommandBulider,用來生成Sql命令,修改數據源,從而直接更改數據表的內容。

  前提是:

    1.這個表必須有主鍵,否則該對象無法生成Update和delete、insert的Sql命令,報異常:

     對於不返回任何鍵列信息的 SelectCommand,不支持 UpdateCommand 的動態 SQL 生成。

    2.實例化SqlCommandBuilder對象的數據適配器對象SqlDataAdapter必須預先設置好SelectCommand屬性

    3.更新的表中不能包括image類型的字段(列)

  由於出錯的情況有很多,程序員無法完全掌握,所以我們強烈建議將更新代碼寫在try catch里

 下面是此方法的實例:

  

     /// <summary>
        /// 數據適配器
        /// </summary>
        SqlDataAdapter adapter = null;
        /// <summary>
        /// 數據集對象
        /// </summary>
        DataSet dSet = null;

        /// <summary>
        /// 連接字符串
        /// </summary>
        private static string strConn = "server=.\\sqlexpress;database=MySchool;uid=sa;pwd=123456";

        /// <summary>
        /// 窗體加載事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form3_Load(object sender, EventArgs e)
        {
            adapter = new SqlDataAdapter("select * from UserInfo", strConn);
            dSet = new DataSet();
            adapter.Fill(dSet);

            DGVMain.DataSource = dSet.Tables[0];
        }

        /// <summary>
        /// 更新按鈕點擊事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            //創建命令重建對象
            SqlCommandBuilder scb = new SqlCommandBuilder(adapter);

            //更新數據
            try
            {
         //這里是關鍵 adapter.Update(dSet); }
catch (SqlException ex) { MessageBox.Show(ex.Message); } }

由於各種原因,性能問題,安全問題和其他復雜的因素。

主要缺點:

1、 基於單表,只能對一個數據源表進行更新,如果要更新數據庫
中的已改變的表,則不能用它來更新了。 

2、 要求數據庫中必須設置好主鍵字段 

3、 不能對存有圖片的數據庫進行增刪改操作 

4、 執行起來,速度相對於非自動化慢(當然,是在數據庫的規模
很大的情況下)

需要注意的地方:

1、 必須與DataAdapter結合使用 
2、 實例化SqlCommandBuilder對象前,必須先指定好數據適配器
的填充命令(SelectCommand)。 
3、 填充命令(Select 語句)中返回的列要包括主鍵列,否則將無
法產生Update,和Delete語句。 
4、  使用命令構建器比手動編寫SQL更好,但是它們只能處理一個
表,底層的數據庫表必須有主鍵或唯一鍵。另外,數據適配器的SelectCommand屬性必須有一個包含主鍵的查詢。

這種方法在實際項目中根本不會用到,一些小項目和初學者可以嘗試。

 

 

第二種方法:定位被修改的單元格,獲取列名和id,構建SQL然后,然后執行更新操作。

  這種方法比第一張方法復雜多,效果卻是一樣的,一般也不太會去用。這里簡單介紹一下。思路是:點擊單元格觸發DGV的CellBeginEdit事件,在此事件中保存原先的值到成員字段中,然后在DGV的CellEndEdit事件中修改數據,執行更新。

  具體的代碼:

  

#region DGV直接編輯修改數據的功能
        /// <summary>
        /// 用來存放DGV單元格修改之前值
        /// </summary>
        Object cellTempValue = null;

        /// <summary>
        /// DGV單元格開始編輯時觸發的事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DGVMain_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
        {
            cellTempValue = DGVMain.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
        }

        /// <summary>
        /// DGV單元格結束編輯時觸發的事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DGVMain_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            //判斷編輯前后的值是否一樣(是否修改了內容)
            if (Object.Equals(cellTempValue, DGVMain.Rows[e.RowIndex].Cells[e.ColumnIndex].Value))
            {
                //如果沒有修改,則返回
                return;
            }

            //判斷用戶是否確定修改
            if (MessageBox.Show("確定修改?", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.None) != DialogResult.OK)
            {
                //如果不修改,恢復原來的值
                DGVMain.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = cellTempValue;
                return;
            }

            //修改數據庫的數據
            string sql = String.Format("update  set {1}='{2}' where 商品編號='{3}'",
                DGVMain.Columns[0].DataPropertyName,         //所選單元格列名
                DGVMain.Rows[e.RowIndex].Cells[e.ColumnIndex].Value,    //所選單元格修改后的值
                DGVMain.Rows[e.RowIndex].Cells[0].Value                  //所選行的商品編號
            );

            try
            {
                OleDbHelper.ExecuteNonQuery(CommandType.Text, sql);
            }
            catch (OleDbException ex)
            {
                MessageBox.Show(ex.Message);
            }

            //刷新數據
            LoadDGV();
        } 
        #endregion

 

個人建議的解決方案:做一個ContextMenu菜單,綁定DGV,菜單中有修改數據和刪除數據,當用戶選擇整行后,點擊右鍵選擇修改信息,立即彈出一個窗口,根據該行的id重新從數據庫中取出該行記錄的所有值,賦值到各個文本框中,然后點擊更新,執行更新操作。這是最最純潔的方法。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM