文件首頁
MySQL Connector/NET 開發人員指南
相關文件 下載本手冊
PDF (美式信紙) - 1.3Mb
PDF (A4) - 1.3Mb


MySQL Connector/NET 開發人員指南  /  Connector/NET 常見問題

第 10 章 Connector/NET 常見問題

問題

  • 10.1: 在交易開始後執行的所有命令是否會自動加入交易?

  • 10.2: 我要如何取得自動遞增欄位的值?

問題與解答

10.1: 在交易開始後執行的所有命令是否會自動加入交易?

是的。當用戶端在傳統 MySQL 中開始交易時,所有後續命令(在該連線上)都是該交易的一部分,直到用戶端提交或回復該交易為止。若要在該交易之外執行命令,您必須開啟單獨的連線。

10.2: 我要如何取得自動遞增欄位的值?

使用 CommandBuilder 時,將 ReturnGeneratedIdentifiers 屬性設定為 true 將不再有效,因為 CommandBuilder 預設不會加入 last_insert_id()

CommandBuilder 會連結到 DataAdapter.RowUpdating 事件處理常式,這表示會為每一列呼叫它。它會檢查命令物件,如果它是相同的參考物件,它基本上會重建該物件,進而破壞您的命令文字變更。

解決此問題的一種方法是複製命令物件,讓您擁有不同的實際參考

dataAdapter.InsertCommand = cb.GetInsertCommand().Clone()

這樣做有效,但由於 CommandBuilder 仍然連接到 DataAdapter,RowUpdating 事件仍然會觸發,從而對效能產生不利影響。為了停止這種情況,一旦新增所有命令後,您需要將 CommandBuilder 從 DataAdapter 中斷連線

cb.DataAdapter = null;

最後一個要求是確保 last_insert_id() 傳回的 id 具有正確的名稱。例如

SELECT last_insert_id() AS id

以下顯示一個完整的運作範例

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Data;
using MySql.Data;
using MySql.Data.MySqlClient;

namespace GetAutoIncId
{
    class Program
    {
        static void Main(string[] args)
        {
            string connStr = "server=localhost;user=root;database=TestDB;port=3306;password=******;";
            MySqlConnection conn = new MySqlConnection(connStr);

            try
            {
                Console.WriteLine("Connecting to MySQL...");
                conn.Open();

                string sql = "SELECT * FROM TestTable";

                MySqlDataAdapter da = new MySqlDataAdapter(sql, conn);
                MySqlCommandBuilder cb = new MySqlCommandBuilder(da);

                MySqlCommand cmd = new MySqlCommand();
                cmd.Connection = conn;
                cmd.CommandText = sql;
                // use Cloned object to avoid .NET rebuilding the object, and
                // thereby throwing away our command text additions.
                MySqlCommand insertCmd = cb.GetInsertCommand().Clone();
                insertCmd.CommandText = insertCmd.CommandText + ";SELECT last_insert_id() AS id";
                insertCmd.UpdatedRowSource = UpdateRowSource.FirstReturnedRecord;
                da.InsertCommand = insertCmd;
                cb.DataAdapter = null; // Unhook RowUpdating event handler

                DataTable dt = new DataTable();
                da.Fill(dt);

                DataRow row = dt.NewRow();
                row["name"] = "Joe Smith";

                dt.Rows.Add(row);
                da.Update(dt);

                System.Console.WriteLine("ID after update: " + row["id"]);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }

            conn.Close();
            Console.WriteLine("Done.");
        }
    }
}