Skip to content

Epic: EF Core migration generation from Weasel schema objects #371

Description

@jeremydmiller

Goal

First-class EF Core migration artifact generation from Weasel schema objects: translate everything an IDatabase knows about (tables, columns, indexes, FKs, sequences, functions, partitions) into compilable EF Core migration classes/files, so that Marten, Polecat, and Wolverine users can ship schema changes through the standard EF toolchain — dotnet ef database update, idempotent scripts, migration bundles, __EFMigrationsHistory.

This is the reverse of the existing Weasel.EntityFrameworkCore direction (MapToTable: EF DbContext → Weasel tables, where Weasel applies the migration). Here Weasel authors the migrations and EF applies them.

Why

  • Teams mixing EF Core with Marten/Polecat/Wolverine in one application get a single artifact format and deployment pipeline for all schema changes.
  • DBA/CI-review workflows built around EF migrations (scripts, bundles) work for critter-stack schema objects.
  • Prior art gap: nothing in the ecosystem generates EF migration files from an external schema definition. Bloomberg's Sable (archived July 2026) is the closest workflow precedent, but it emitted plain SQL and its diff engine was Marten's own marten-patch — i.e., Weasel already owns the hard part.

Architecture (decided)

  • Direct emission: Weasel typed model/deltas → hand-rolled C# emitter of MigrationBuilder calls + [DbContext]/[Migration] attributes. No EF design-time scaffolding APIs (pubternal; Scaffolding Migrations programmatically in Asp.Net Core 5 and EF Core 5 dotnet/efcore#23595 closed as not-planned).
  • Attribute-only migrations with empty BuildTargetModel — runtime-valid; verified by spike (Spike: attribute-only EF Core migrations without a real EF model #364). EF 9+ requires suppressing RelationalEventId.PendingModelChangesWarning in the generated stub context.
  • Coexistence via multi-context EF: one Weasel-owned stub DbContext per IDatabase, history table relocated into the critter-stack schema, so generated migrations never collide with the user's own app-context migrations. Supports any mix of EF Core + Marten + Polecat + Wolverine.
  • EF Core projections round-trip automatically: projection DbContext → MapToTableIDatabase.AllObjects() → generated artifacts.
  • Raw-SQL fallback (migrationBuilder.Sql()) for everything EF can't model: PG partitioning, PL/pgSQL functions, SQL Server procedures/table types, sequence default expressions, rich index options.
  • Snapshot baseline without a shadow database: serialized Weasel schema snapshot (JSON) diffed in memory via TableDelta — improves on Sable's Testcontainers-replay approach.
  • IDatabase is the single source of schema objects, same as the existing db-* commands.
  • v1 providers: PostgreSQL + SQL Server; SQLite pending spike outcome; Oracle/MySQL later.

Phases

Rough ordering: #363 and #364 can run in parallel and first; #365#366#367#368 build on each other; #369 grows alongside #365#368; #370 lands last.

Out of scope (tracked downstream)

  • Marten / Polecat / Wolverine consumption docs and any thin registration helpers — no engine changes expected there, since everything flows through IDatabase.
  • dotnet ef migrations add/remove against the Weasel stub context is explicitly unsupported (documented in EF migration generation: documentation #370).

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions