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:
// PostgreSQL
await pgTable.ApplyChangesAsync(npgsqlConnection);
// SQL Server
await ssTable.ApplyChangesAsync(sqlConnection);
// SQLite
await sqliteTable.ApplyChangesAsync(sqliteConnection);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:
// PostgreSQL
await pgTable.CreateAsync(npgsqlConnection);
// SQL Server
await ssTable.CreateAsync(sqlConnection);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:
// PostgreSQL
await pgTable.DropAsync(npgsqlConnection);
// SQL Server
await ssTable.Drop(sqlConnection);MigrateAsync
Creates or updates the object based on delta detection, respecting an AutoCreate policy:
// PostgreSQL -- defaults to AutoCreate.CreateOrUpdate
bool changed = await table.MigrateAsync(npgsqlConnection);
// With explicit policy
changed = await table.MigrateAsync(
npgsqlConnection,
autoCreate: AutoCreate.CreateOnly
);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:
var objects = new ISchemaObject[] { usersTable, ordersTable, sequence };
bool changed = await objects.MigrateAsync(sqlConnection);EnsureSchemaExists
Creates a database schema if it does not already exist (PostgreSQL and SQL Server):
// PostgreSQL
await npgsqlConnection.EnsureSchemaExists("myapp");
// SQL Server
await sqlConnection.EnsureSchemaExists("myapp");SQLite does not need this method because it only supports the built-in main and temp schemas.
Full PostgreSQL Example
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);Full SQL Server Example
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);Full SQLite Example
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);CommandBuilder Extensions
Beyond schema objects, Weasel also provides extensions on CommandBuilderBase for executing commands:
| Method | Purpose |
|---|---|
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.
| Extension | PostgreSQL | SQL Server | Oracle | SQLite |
|---|---|---|---|---|
ApplyChangesAsync | Yes | Yes | Yes | Yes |
CreateAsync | Yes | Yes | Yes | Yes |
DropAsync | Yes | Yes | Yes | Yes |
MigrateAsync | Yes | Yes | Yes | Yes |
EnsureSchemaExists | Yes | Yes | No | No |
