/// <summary> /// Initializes the database. /// </summary> /// <param name="context">The context.</param> public virtual void InitializeDatabase(TContext context) { if (_initializedContextTypes.Contains(context.GetType())) { return; } if (!context.Database.Exists()) { throw Error.InvalidOperation("Database migration failed because the target database does not exist. Ensure the database was initialized and seeded with the 'InstallDatabaseInitializer'."); } var config = CreateConfiguration(); var migrator = new DbSeedingMigrator <TContext>(config); using (new DbContextScope(context as IDbContext, hooksEnabled: false)) { // run all pending migrations var appliedCount = migrator.RunPendingMigrations(context); if (appliedCount > 0) { Seed(context); } else { // DB is up-to-date and no migration ran. EfMappingViewCacheFactory.SetContext(context); if (config is MigrationsConfiguration coreConfig && context is SmartObjectContext ctx) { // Call the main Seed method anyway (on every startup), // we could have locale resources or settings to add/update. coreConfig.SeedDatabase(ctx); } } // not needed anymore this.DataSeeders = null; _initializedContextTypes.Add(context.GetType()); } }
protected virtual async Task InitializeDatabaseAsync(DbMigrator migrator, IEnumerable <Type> seederTypes, CancellationToken cancelToken = default) { Guard.NotNull(migrator, nameof(migrator)); var context = migrator.Context; var type = context.GetInvariantType(); if (_initializedContextTypes.Contains(type)) { return; } if (!await context.Database.CanConnectAsync(cancelToken)) { throw new InvalidOperationException($"Database migration failed because the target database does not exist. Ensure the database was initialized and properly seeded with data."); } using (new DbContextScope(context, minHookImportance: HookImportance.Essential)) { // Set (usually longer) command timeout for migrations var prevCommandTimeout = context.Database.GetCommandTimeout(); if (_appConfig.DbMigrationCommandTimeout.HasValue && _appConfig.DbMigrationCommandTimeout.Value > 15) { context.Database.SetCommandTimeout(_appConfig.DbMigrationCommandTimeout.Value); } // Run all pending migrations await migrator.RunPendingMigrationsAsync(cancelToken); // Execute the global seeders anyway (on every startup), // we could have locale resources or settings to add/update. await RunGlobalSeeders(context, seederTypes, cancelToken); // Restore standard command timeout context.Database.SetCommandTimeout(prevCommandTimeout); _initializedContextTypes.Add(type); } }