Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 2, 2026

Fixes #37431

Description

Migrations are no longer discovered if the DbContextAttribute is placed on a base class rather than the concrete migration class.

The fix manually walks the type inheritance chain to find the first DbContextAttribute, which supports inheritance while avoiding AmbiguousMatchException by preferring the most derived class's attribute.

Customer impact

Customers using a base migration class with [DbContext] attribute on the base class and not on the derived classes cannot use migrations in EF Core 10 RC2. The migration discovery fails completely, preventing any migration operations from working.

Workaround: Customers must add the [DbContext] attribute to each individual migration class instead of using a base class pattern, which adds repetitive boilerplate code. However, There are no exceptions thrown, updating the database just prints a message saying that no migrations were found, so it would take some intuition in how the migrations infrastructure works and a guess for where the bug might be to find the workaround naturally. And since this is a regression then the person debugging this could be different from the person that created the base types for the migrations initially.

How found

Customer reported via npgsql/efcore.pg#3697. But the issue affects all database providers, not just Npgsql. However, this is not a common pattern as the migrations generated by EF do not derive from any class.

Regression

Yes, regression from EF Core 9.0. It was introduced in EF Core 10.0.0-rc.2 via #36666,

Testing

Test added

Risk

Low. The change only affects the design-time tools.

Original prompt

This section details on the original issue you should resolve

<issue_title>Migration classes no longer detected with [DbContext] on base class</issue_title>
<issue_description>@AndriySvyryd am not sure if the below was intentional or not, PTAL.

AI summary:

Summary of Findings

The issue is a general EF Core 10 regression affecting all database providers (confirmed on both PostgreSQL and SQL Server). Migrations are no longer discovered if the [DbContext] attribute is placed on a base class rather than the concrete migration class.

###Root Cause
The regression was introduced in EF Core 10.0.0-rc.2 via PR #36666 in the dotnet/efcore repository. This PR was intended to fix Issue #35590, where multiple [DbContext] attributes in an inheritance hierarchy caused an AmbiguousMatchException.

To fix that, the discovery logic in src/EFCore.Relational/Migrations/Internal/MigrationsAssembly.cs was changed to use inherit: false when looking up the DbContextAttribute:

While this prevents the AmbiguousMatchException, it also prevents EF Core from finding the attribute when it is only defined on a base class, which was a supported pattern in EF Core 9.

Minimal repro
using var uow = new UnitOfWork();

var migrations = uow.Database.GetMigrations().ToArray();
Console.WriteLine($"Migrations count: {migrations.Length}");

foreach (var m in migrations)
{
    Console.WriteLine($"- {m}");
}

if (migrations.Length == 0)
{
    throw new Exception("No migrations found!");
}

public class UnitOfWork : DbContext
{
    public DbSet<User> Users => Set<User>();

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        => optionsBuilder
            .UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=efcore_migrations;Trusted_Connection=True")
            .LogTo(Console.WriteLine, LogLevel.Information);
}

public class User
{
    public Guid Id { get; set; }
}

[DbContext(typeof(UnitOfWork))]
public abstract class MigrationBase : Migration
{
}

[Migration("202512271406_CreateUsers")]
public class Migration_202512271406_CreateUsers : MigrationBase
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.CreateTable(
           name: "Users",
           columns: table => new
           {
               Id = table.Column<Guid>(nullable: false),
           },
           constraints: table =>
           {
               table.PrimaryKey("PK_Users", x => x.Id);
           }
        );
    }
}

Originally reported by @Ryba1986 in npgsql/efcore.pg#3697</issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI changed the title [WIP] Fix migration classes detection with DbContext on base class Fix migration discovery when [DbContext] is only on base class Jan 2, 2026
Copilot AI requested a review from AndriySvyryd January 2, 2026 21:05
@AndriySvyryd
Copy link
Member

@copilot Update progress by rewriting the PR summary using this template:

Fixes #{number}

**Description**
{Issue description}

**Customer impact**
{How does the reported issue affects customer's app? Are there workarounds?}

**How found**
{Was it customer reported or found during verification? How many customers are affected?}

**Regression**
{Is it a regression from a released version? Which one?}

**Testing**
{How the changes were tested}

**Risk**
{Low/Medium/High, argument why}

Copy link
Contributor Author

Copilot AI commented Jan 2, 2026

@copilot Update progress by rewriting the PR summary using this template:

...

Updated the PR description to follow the standard template format.

@AndriySvyryd AndriySvyryd removed their request for review January 3, 2026 01:26
@AndriySvyryd AndriySvyryd marked this pull request as ready for review January 3, 2026 01:26
@AndriySvyryd AndriySvyryd requested a review from a team as a code owner January 3, 2026 01:26
Copilot AI review requested due to automatic review settings January 3, 2026 01:26
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a regression in EF Core 10 RC2 where migrations are no longer discovered when the [DbContext] attribute is placed only on a base migration class rather than on the concrete migration classes. The fix manually walks the type inheritance chain to find the first DbContextAttribute, avoiding AmbiguousMatchException while restoring support for inherited attributes.

Key Changes:

  • Adds a GetDbContextType helper method that manually traverses the inheritance hierarchy to find the DbContextAttribute
  • Replaces direct GetCustomAttribute calls with the new helper method in both migration and model snapshot discovery
  • Adds comprehensive test coverage for the scenario where the attribute is only on the base class

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/EFCore.Relational/Migrations/Internal/MigrationsAssembly.cs Introduces GetDbContextType helper method that walks the inheritance chain to find DbContextAttribute, replacing direct GetCustomAttribute calls in migration and model snapshot discovery
test/EFCore.Relational.Tests/Migrations/Internal/MigrationsAssemblyTest.cs Adds test case Migrations_finds_attribute_on_base_class_only to verify migrations are discovered when [DbContext] attribute is only on base class, with supporting test infrastructure

@AndriySvyryd AndriySvyryd changed the title Fix migration discovery when [DbContext] is only on base class [release/10.0] Fix migration discovery when [DbContext] is only on base class Jan 3, 2026
@AndriySvyryd AndriySvyryd requested a review from artl93 January 6, 2026 01:08
@AndriySvyryd
Copy link
Member

cc @artl93

Copy link
Member

@artl93 artl93 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Customer reported regression, but uncommon. How discoverable is the workaround?

@artl93 artl93 self-requested a review January 6, 2026 17:27
@AndriySvyryd
Copy link
Member

The are no exceptions thrown, updating the database just prints a message saying that no migrations were found, so it would take some intuition in how the migrations infrastructure works and a guess for where the bug might be to find the workaround naturally. And since this is a regression then the person debugging this could be different from the person that created the base types for the migrations initially.
So I estimate that it would take at least a couple of days to find and implement the workaround for every affected customer

@artl93
Copy link
Member

artl93 commented Jan 6, 2026

Thanks - approved. Please state this about the workaround in the tactics mail.

Copy link
Member

@artl93 artl93 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See prior comment

@AndriySvyryd AndriySvyryd merged commit 5fbeb1f into release/10.0 Jan 7, 2026
13 of 14 checks passed
@AndriySvyryd AndriySvyryd deleted the copilot/fix-migration-classes-detection branch January 7, 2026 00:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants