Search code examples
c#.net-coreentity-framework-coreazure-sql-database

The default schema does not exist EF Core Migration


I'm using .Net Core 6 with EF Core (Code First) and Azure SQL. When i run the add-migration command it generates the file and when I run the update-database command I get the below error.

enter image description here

Also the update-database command works when I have my connection string to local DB. The issue comes only when connection string is changed to Azure SQL and that connection string is got from Azure KeyVault.

Tried,

In DbContext:

 protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
 {
     var relationalOptions = RelationalOptionsExtension.Extract(optionsBuilder.Options);
     relationalOptions.WithMigrationsHistoryTableName("EFMigrationHistory");
     relationalOptions.WithMigrationsHistoryTableSchema("dbo");
 }

In Program.cs:

using (var scope = app.Services.CreateScope())
{
    var db = scope.ServiceProvider.GetRequiredService<NotificationDbContext>();
    db.Database.Migrate();
}

Same error again. Can someone help?


Solution

  • I faced a similar problem and solved using a different approach between design time and runtime as suggested in Design-time DbContext Creation (MS learn).

    To work at design time, I defined a class derived from IDesignTimeDbContextFactory. This class is automatically detected by update-database or dotnet CLI when you perform a migration.

    public class MyDbContextFactory : IDesignTimeDbContextFactory<MyDbContext> {
        public MyDbContext CreateDbContext(string[] args) {
            var optionsBuilder = new DbContextOptionsBuilder<MyDbContext>();
            optionsBuilder.UseSqlServer("... connection string here ..."
                , options => {
                    options.MigrationsHistoryTable("EFMigrationHistory", "dbo");
                });
    
            return new MyDbContext(optionsBuilder.Options); 
        }
    }
    

    To work at run time, e.g. if you want to perform database update at the startup, the previous class is not used. To set the migration history table at run time I set the migration history using sql sqlServerOptionsAction parameter in UseSqlServer method:

    builder.Services.AddDbContext<MyDbContext>(options => {
        options.UseSqlServer(builder.Configuration.GetConnectionString("dbConnection"),
            sqlServerOptionsAction: sqlOptions => {
                sqlOptions.MigrationsHistoryTable("EFMigrationHistory", "dbo");
                sqlOptions.MigrationsAssembly(typeof(MyDbContext).Assembly.GetName().Name);
                sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null);
            });
    }, ServiceLifetime.Scoped);