MySQL Connector/NET 发行说明
问题
问题与解答
10.1: 事务开始后执行的所有命令是否都会自动登记到事务中?
是的。当客户端在经典 MySQL 中开始事务时,所有后续命令(在该连接上)都是该事务的一部分,直到客户端提交或回滚该事务。要在该事务之外执行命令,必须打开一个单独的连接。
使用 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.");
}
}
}