Глава 10 Connector/NET ЧаВо
Вопросы
Вопросы и ответы
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;
Последнее требование заключается в том, чтобы убедиться, что id, возвращаемый last_insert_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.");
}
}
}
© 2025 Oracle
Licensed under the GPLv2 License.