文档主页
MySQL Connector/NET 开发者指南
相关文档 下载本手册
PDF (US Ltr) - 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 事件处理程序,这意味着它会针对每一行调用。它会检查命令对象,如果它是同一个被引用的对象,它实际上会重建该对象,从而破坏您的命令文本更改。

解决此问题的一种方法是克隆命令对象,以便您拥有不同的实际引用。

Press CTRL+C to copy
dataAdapter.InsertCommand = cb.GetInsertCommand().Clone()

这有效,但由于 CommandBuilder 仍然连接到 DataAdapter,因此 RowUpdating 事件仍然会触发,从而对性能产生负面影响。要阻止这种情况,一旦添加了所有命令,就需要断开 CommandBuilder 与 DataAdapter 的连接。

Press CTRL+C to copy
cb.DataAdapter = null;

最后一个要求是确保 last_insert_id() 返回的 id 具有正确的名称。例如:

Press CTRL+C to copy
SELECT last_insert_id() AS id

此处显示了一个完整的工作示例。

Press CTRL+C to copy
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."); } } }