Skip to content

Extension Methods ​

Each Weasel provider ships a SchemaObjectsExtensions class with convenience methods that make it easy to create, drop, migrate, and apply changes to individual schema objects using a single method call. These extensions wrap the delta detection and DDL generation pipeline behind simple async APIs.

SchemaObjectsExtensions ​

Every provider (Weasel.Postgresql, Weasel.SqlServer, Weasel.Oracle, Weasel.Sqlite) defines its own parallel set of these extension methods, each typed to the provider's connection class.

ApplyChangesAsync ​

Detects differences between the configured schema object and the actual database, then applies any needed DDL:

cs
// PostgreSQL
await pgTable.ApplyChangesAsync(npgsqlConnection);

// SQL Server
await ssTable.ApplyChangesAsync(sqlConnection);

// SQLite
await sqliteTable.ApplyChangesAsync(sqliteConnection);

snippet source | anchor

This is the most common method for keeping a single object in sync with the database. It runs the full detect-and-apply cycle.

CreateAsync ​

Generates and executes only the creation DDL, without checking whether the object already exists:

cs
// PostgreSQL
await pgTable.CreateAsync(npgsqlConnection);

// SQL Server
await ssTable.CreateAsync(sqlConnection);

snippet source | anchor

Use this when you know the object does not exist yet (e.g., during initial setup or testing).

DropAsync ​

Generates and executes the drop DDL:

cs
// PostgreSQL
await pgTable.DropAsync(npgsqlConnection);

// SQL Server
await ssTable.Drop(sqlConnection);

snippet source | anchor

MigrateAsync ​

Creates or updates the object based on delta detection, respecting an AutoCreate policy:

cs
// PostgreSQL -- defaults to AutoCreate.CreateOrUpdate
bool changed = await table.MigrateAsync(npgsqlConnection);

// With explicit policy
changed = await table.MigrateAsync(
    npgsqlConnection,
    autoCreate: AutoCreate.CreateOnly
);

snippet source | anchor

Returns true if any changes were applied, false if the object was already up to date. You can also migrate an array of objects together:

cs
var objects = new ISchemaObject[] { usersTable, ordersTable, sequence };
bool changed = await objects.MigrateAsync(sqlConnection);

snippet source | anchor

EnsureSchemaExists ​

Creates a database schema if it does not already exist (PostgreSQL and SQL Server):

cs
// PostgreSQL
await npgsqlConnection.EnsureSchemaExists("myapp");

// SQL Server
await sqlConnection.EnsureSchemaExists("myapp");

snippet source | anchor

SQLite does not need this method because it only supports the built-in main and temp schemas.

Full PostgreSQL Example ​

cs
await using var dataSource = NpgsqlDataSource.Create(connectionString);
await using var conn = await dataSource.OpenConnectionAsync();

// Ensure the schema exists
await conn.EnsureSchemaExists("myapp");

// Define a table
var table = new Weasel.Postgresql.Tables.Table(new PostgresqlObjectName("myapp", "people"));
table.AddColumn<int>("id").AsPrimaryKey();
table.AddColumn<string>("name").NotNull();
table.AddColumn<string>("email");

// Apply changes -- creates the table if missing, updates if changed
await table.ApplyChangesAsync(conn);

snippet source | anchor

Full SQL Server Example ​

cs
await using var conn = new SqlConnection(connectionString);
await conn.OpenAsync();

await conn.EnsureSchemaExists("myapp");

var table = new Weasel.SqlServer.Tables.Table(new SqlServerObjectName("myapp", "people"));
table.AddColumn<int>("id").AsPrimaryKey();
table.AddColumn<string>("name").NotNull();
table.AddColumn<string>("email");

await table.ApplyChangesAsync(conn);

snippet source | anchor

Full SQLite Example ​

cs
await using var conn = new SqliteConnection("Data Source=myapp.db");
await conn.OpenAsync();

// Apply PRAGMA settings for performance
var pragmas = new SqlitePragmaSettings
{
    JournalMode = JournalMode.WAL,
    ForeignKeys = true
};
await pragmas.ApplyToConnectionAsync(conn);

var table = new Weasel.Sqlite.Tables.Table("people");
table.AddColumn<int>("id").AsPrimaryKey().AutoIncrement();
table.AddColumn<string>("name").NotNull();
table.AddColumn<string>("email");

await table.ApplyChangesAsync(conn);

snippet source | anchor

CommandBuilder Extensions ​

Beyond schema objects, Weasel also provides extensions on CommandBuilderBase for executing commands:

MethodPurpose
ExecuteNonQueryAsync()Execute the command without reading results.
ExecuteReaderAsync()Execute and return a DbDataReader.
FetchListAsync<T>()Execute, read all rows, and materialize a List<T>.

These are used internally by Weasel's migration infrastructure and are available for your own database operations.

Provider Parity ​

Each provider implements the same set of extension methods with the same signatures (adjusted for connection type). This means switching providers requires only changing the using directive and connection type -- the calling code stays the same.

ExtensionPostgreSQLSQL ServerOracleSQLite
ApplyChangesAsyncYesYesYesYes
CreateAsyncYesYesYesYes
DropAsyncYesYesYesYes
MigrateAsyncYesYesYesYes
EnsureSchemaExistsYesYesNoNo

Released under the MIT License.