/// <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());
            }
        }
Beispiel #2
0
        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);
            }
        }