MySQL Overview
Weasel.MySql provides schema management and migration support for MySQL databases using the MySqlConnector driver.
Installation
dotnet add package Weasel.MySqlKey Components
- MySqlProvider -- Singleton at
MySqlProvider.Instancethat handles type mappings and identifier parsing. The default schema ispublic; see Schemas are databases. - MySqlMigrator -- Generates DDL scripts and executes schema migrations. Identifiers are quoted with backticks.
Supported Schema Objects
| Object | Class | Namespace |
|---|---|---|
| Tables | Table | Weasel.MySql.Tables |
| Sequences | Sequence | Weasel.MySql |
Connection String
Weasel.MySql uses standard MySQL connection strings compatible with MySqlConnector:
var connectionString = "Server=localhost;Database=mydb;User=root;Password=YourPassword;";Type Mappings
| .NET Type | MySQL Type |
|---|---|
string | VARCHAR(255) |
int | INT |
long | BIGINT |
bool | TINYINT(1) |
decimal | DECIMAL(18,2) |
double | DOUBLE |
DateTime | DATETIME |
Guid | CHAR(36) |
byte[] | BLOB |
Creating a Migrator
var migrator = new MySqlMigrator();The migrator can ensure the target database exists:
await using var conn = new MySqlConnection(connectionString);
await migrator.EnsureDatabaseExistsAsync(conn);
// Generates: CREATE DATABASE IF NOT EXISTS `mydb`;Schemas are databases
MySQL has no schemas inside a database: CREATE SCHEMA is a synonym for CREATE DATABASE. So a Weasel schema name is a MySQL database name, and mydb.users is the table users in the database mydb.
| You write | DDL targets | Introspection reads |
|---|---|---|
new Table("mydb.users") | `mydb`.`users` | TABLE_SCHEMA = 'mydb' |
new Table("users") | `public`.`users` | TABLE_SCHEMA = 'public' |
A table with no schema is not placed in the connection's database. It is placed in a database named public, and the migration fails with 1142 CREATE command denied or 1049 Unknown database 'public' unless that database exists. Name the database explicitly -- the connection's own, if that is where the table belongs:
var database = new MySqlConnectionStringBuilder(connectionString).Database;
var table = new Table(new MySqlObjectName(database, "users"));A migration creates each database it mentions that does not exist yet (CREATE DATABASE IF NOT EXISTS), which needs the CREATE privilege on it. A database that already exists -- the connection's own, typically -- is not created again, so a user that may alter the tables of a database but not create databases can still apply a delta that only changes existing tables.
Identifiers
MySQL delimits with backticks and delimits unconditionally — it is the one provider for which "was this name left bare?" is never the right question. An embedded backtick is escaped by doubling it. A backslash is rejected outright: it is an escape character inside MySQL string literals unless NO_BACKSLASH_ESCAPES is set, so a trailing one would swallow the closing quote of a literal a name is written into.
9.25 normalizes identifiers on the way into the model, which is visible in two places:
Table(DbObjectName)normalizes toMySqlObjectName, soTable.Identifier.QualifiedNamerenders as`schema`.`name`rather thanschema.name.Table(string)already parsed throughMySqlProviderand is unaffected.table.Identifierno longer compares equal to a plainnew DbObjectName(schema, name)for the same table. That inequality was the fix, not the bug — a hand-built identifier never matched the catalog, so foreign keys reported drift on every check.
See Identifiers and Quoting for the cross-provider rules and Upgrading to 9.25 for the migration notes.
