Commands and callbacks

Use the active provider connection when a migration needs driver-level work.

Examples use Classic and Fluent tabs. Your choice follows you through the manual.

Bind command parameters

The provider creates a command associated with its current transaction. Dispose it after use. Generate parameter names through the provider, rather than assuming every driver uses the same convention. The callback is deferred until fluent execution reaches it.

Execute a parameterized command

Classic

using var command = Database.CreateCommand();
var name = Database.GenerateParameterName(0);
command.CommandText = "UPDATE Users SET Name = " + name + " WHERE Id = 1";
var value = command.CreateParameter();
value.ParameterName = name;
value.Value = "Ada";
command.Parameters.Add(value);
command.ExecuteNonQuery();

Fluent

migration.Execute.WithProvider(provider =>
{
    using var command = provider.CreateCommand();
    var name = provider.GenerateParameterName(0);
    command.CommandText = "UPDATE Users SET Name = " + name + " WHERE Id = 1";
    var value = command.CreateParameter();
    value.ParameterName = name;
    value.Value = "Ada";
    command.Parameters.Add(value);
    command.ExecuteNonQuery();
});

Inside Up() / BuildUp(MigrationBuilder migration)

Connection ownership

WithCommand creates and disposes a provider command around your action. WithConnection exposes the connection; WithProvider exposes the complete transformation provider. Do not close or replace a runner-owned connection, commit its transaction or switch databases while holding a native migration lock.

Database administration

Database creation and other administration require a connection and identity authorized for that operation. Use a dedicated host with TransactionMode.None. Fluent administration rejects an active transaction; do not combine it with WholeSession or assume a Classic provider call can participate in transactional DDL.

Create a database on a supporting server

Classic

Database.CreateDatabases("Reporting");

Fluent

migration.Administration.CreateDatabase("Reporting");

Inside Up() / BuildUp(MigrationBuilder migration)

The remaining mappings are DropDatabases / Administration.DropDatabase, SwitchDatabase / Administration.SwitchDatabase, and KillDatabaseConnections / Administration.KillConnections. These are explicit administrative actions with provider-specific support. Database switches invalidate assumptions about migration history and session locks: keep provisioning separate from ordinary schema migrations. They are outside SQL preview and automatic reversal.

Preview and reversal

Callbacks can perform arbitrary C# work and cannot be translated into SQL preview. They require explicit reverse behavior. Keeping external network calls out of migration bodies makes failures easier to reason about: a database rollback cannot undo an email or an HTTP request.