Skip to content

HasPendingModelChanges() always returns true #34967

Description

@charlesRollandy

I have an application with a database project and a data migration project. I wrote a unit test in a dedicated project to test there is no pending changes in my model and no migration is required.

My solution has the following structure:

MySolution
├ Database/
|    ├ Entities/
|    |     User.cs
|    |     Group.cs
|    |     ...
|    AppDbContext.cs   
├ Database.Migrations/
|    ├ Migrations/
|    DesignTimeDbContextFactory.cs
├ App.UnitTests/
|    AppDbContextTests.cs   

This us my unit test in AppDbContext.cs:

public class AppDbContextTests
{
    [Test]
    public void Database_shouldNotHavePendingModelChanges()
    {
        using(var context = CreateAppDbContext())
        {
            var hasChanges = context.Database.HasPendingModelChanges();
            Assert.That(hasChanges, Is.False, "The dabatase has model changes pending. Create a new migration for it.");
        }        
    }

    private AppDbContext CreateAppDbContext()
    {
        var connection = new SqliteConnection("Filename=:memory:");
        connection.Open();
        
        var dbContextOptions = new DbContextOptionsBuilder<AppDbContext>()
            .UseSqlite(
                connection,
                b => b.MigrationsAssembly(Assembly.GetAssembly(typeof(DesignTimeDbContextFactory))!.GetName().Name))
            .Options;
        
        return new AppDbContext(dbContextOptions);
    }
}

This test always fails. HasPendingModelChanges always returns true

This is the code of DesignTimeDbContextFactory.cs

public class DesignTimeDbContextFactory: IDesignTimeDbContextFactory<AppDbContext>
{
    public AppDbContext CreateDbContext(string[] args)
    {
        // Build config
        IConfiguration config = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
# if DEBUG
            .AddJsonFile($"appsettings.local.json")
#endif
            .AddEnvironmentVariables()
            .Build();

        // Get connection string
        var optionsBuilder = new DbContextOptionsBuilder<AppDbContext>();
        optionsBuilder.UseSqlServer(config.GetValue<string>(AppDbContext.ConfigurationKey),
            b => b.MigrationsAssembly(Assembly.GetExecutingAssembly().GetName().Name));
        return new AppDbContext(optionsBuilder.Options);
    }
}

When I open a terminal from the Database.Migrations folder and run the command dotnet ef migrations has-pending-model-changes it gives me the correct result.
I tried using the same database provider in my unit test but the result was the same. It doesn't look to be related to that.

EF Core version: 8.0.10
Target framework: (e.g. .NET 8.0)
Operating system: Windows 11
IDE: (e.g. Visual Studio 2022 17.11.5)

Metadata

Metadata

Assignees

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions