Columns and data types
Type, size, precision, nullability, defaults, identity and collation are explicit column attributes.
Examples use Classic and Fluent tabs. Your choice follows you through the manual.
Explicit table and column steps
Create.Column(name).OnTable(table) and Alter.Column(name).OnTable(table) select the table before exposing type and column options. Delete.Column(name).FromTable(table) completes a removal. For a complete Column model use Create.Column(definition).OnTable(table) or Alter.Column(definition).OnTable(table); the definition is copied. Every named fluent column requires As... or OfType(...) before execution.
Table columns, added columns and altered columns share the same options, including AsGuid, AsBoolean, AsDecimal(precision, scale), AsDate, AsDateTime and AsDateTime2. AsDateTime maps to DbType.DateTime; AsDateTime2 maps to DbType.DateTime2. OfType(DbType) and OfType(MigratorDbType) remain available for other types. Nullability defaults to nullable.
Add and remove a column
Column builders take column name followed by table name. Classic AddColumn takes table name first. New nullable columns accept existing rows without a backfill. A required column usually needs a compatible default or a staged data migration.
Classic
Database.AddColumn("Users", new Column("Email", DbType.String, 320));Fluent
migration.Create.Column("Email").OnTable("Users").AsString(320).Nullable();Inside Up() / BuildUp(MigrationBuilder migration)
Classic
Database.RemoveColumn("Users", "Email");Fluent
migration.Delete.Column("Email").FromTable("Users");Inside Up() / BuildUp(MigrationBuilder migration)
Precision and defaults
For decimal values specify precision and scale. In a Column constructor an integer after the type is the size, not a numeric default. Set DefaultValue explicitly to avoid overload ambiguity. Plain strings are values; trusted SQL expressions use RawSql.Insert.
Classic
Database.AddColumn("Orders", new Column("Amount", DbType.Decimal)
{
Precision = 12, Scale = 4, IsNullable = false, DefaultValue = 0m
});Fluent
migration.Create.Column("Amount").OnTable("Orders").OfType(DbType.Decimal)
.WithPrecision(12, 4).NotNullable().WithDefaultValue(0m);Inside Up() / BuildUp(MigrationBuilder migration)
Time of day and durations
Use TimeOnly for time-of-day values and TimeSpan for intervals. A TimeSpan is a duration, including negative and multi-day values, so a TimeSpan default on a Time column is rejected. PostgreSQL and Oracle have native intervals; SQLite, SQL Server and MySQL/MariaDB store intervals as signed .NET ticks.
Classic
Database.AddTable("Jobs",
new Column("RunAt", DbType.Time) { DefaultValue = new TimeOnly(9, 30) },
new Column("Elapsed", MigratorDbType.Interval) { DefaultValue = TimeSpan.Zero });Fluent
migration.Create.Table("Jobs")
.WithColumn("RunAt").OfType(DbType.Time).WithDefaultValue(new TimeOnly(9, 30))
.WithColumn("Elapsed").OfType(MigratorDbType.Interval).WithDefaultValue(TimeSpan.Zero);Inside Up() / BuildUp(MigrationBuilder migration)
Database storage differs
SQLite does not enforce declared string lengths or decimal precision. UInt64 values above Int64.MaxValue are rejected there. Oracle character empty strings become NULL; Informix and Sybase have their own trimming and range behavior. Consult the type support and boundary matrix for supported mappings and live-test scope. A shared DbType does not imply identical native storage.