/// <summary> /// Runs the plugin migrations for the specified plugin assembly /// </summary> /// <param name="pluginAssembly">The plugin assembly.</param> /// <returns></returns> /// <exception cref="RockStartupException"> /// The '{assemblyName}' plugin assembly contains duplicate migration numbers ({ migrationNumberAttr.Number}). /// or /// ##Plugin Migration error occurred in {assemblyMigrations.Key}, {migrationType.Value.Name}## /// </exception> public static bool RunPluginMigrations(Assembly pluginAssembly) { string pluginAssemblyName = pluginAssembly.GetName().Name; // Migrate any plugins from the plugin assembly that have pending migrations List <Type> pluginMigrationTypes = Rock.Reflection.SearchAssembly(pluginAssembly, typeof(Rock.Plugin.Migration)).Select(a => a.Value).ToList(); // If any plugin migrations types were found if (!pluginMigrationTypes.Any()) { return(false); } bool result = false; // Get the current rock version var rockVersion = new Version(Rock.VersionInfo.VersionInfo.GetRockProductVersionNumber()); // put the migrations to run in a Dictionary so that we can run them in the correct order // based on MigrationNumberAttribute var migrationTypesByNumber = new Dictionary <int, Type>(); // Iterate plugin migrations foreach (var migrationType in pluginMigrationTypes) { // Get the MigrationNumberAttribute for the migration var migrationNumberAttr = migrationType.GetCustomAttribute <Rock.Plugin.MigrationNumberAttribute>(); if (migrationNumberAttr != null) { // If the migration's minimum Rock version is less than or equal to the current rock version, add it to the list var minRockVersion = new Version(migrationNumberAttr.MinimumRockVersion); if (minRockVersion.CompareTo(rockVersion) <= 0) { // Check to make sure no another migration has same number if (migrationTypesByNumber.ContainsKey(migrationNumberAttr.Number)) { throw new RockStartupException($"The '{pluginAssemblyName}' plugin assembly contains duplicate migration numbers ({ migrationNumberAttr.Number})."); } migrationTypesByNumber.Add(migrationNumberAttr.Number, migrationType); } } } // Create EF service for plugin migrations var rockContext = new RockContext(); var pluginMigrationService = new PluginMigrationService(rockContext); // Get the versions that have already been installed var installedMigrationNumbers = pluginMigrationService.Queryable() .Where(m => m.PluginAssemblyName == pluginAssemblyName) .Select(a => a.MigrationNumber); // narrow it down to migrations that haven't already been installed migrationTypesByNumber = migrationTypesByNumber .Where(a => !installedMigrationNumbers.Contains(a.Key)) .ToDictionary(k => k.Key, v => v.Value); // Iterate each migration in the assembly in MigrationNumber order var migrationTypesToRun = migrationTypesByNumber.OrderBy(a => a.Key).Select(a => a.Value).ToList(); var configConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["RockContext"]?.ConnectionString; try { using (var sqlConnection = new SqlConnection(configConnectionString)) { try { sqlConnection.Open(); } catch (SqlException ex) { throw new RockStartupException("Error connecting to the SQL database. Please check the 'RockContext' connection string in the web.ConnectionString.config file.", ex); } // Iterate thru each plugin migration in this assembly, if one fails, will log the exception and stop running migrations for this assembly foreach (Type migrationType in migrationTypesToRun) { int migrationNumber = migrationType.GetCustomAttribute <Rock.Plugin.MigrationNumberAttribute>().Number; using (var sqlTxn = sqlConnection.BeginTransaction()) { bool transactionActive = true; try { // Create an instance of the migration and run the up migration var migration = Activator.CreateInstance(migrationType) as Rock.Plugin.Migration; migration.SqlConnection = sqlConnection; migration.SqlTransaction = sqlTxn; migration.Up(); sqlTxn.Commit(); transactionActive = false; // Save the plugin migration version so that it is not run again var pluginMigration = new PluginMigration(); pluginMigration.PluginAssemblyName = pluginAssemblyName; pluginMigration.MigrationNumber = migrationNumber; pluginMigration.MigrationName = migrationType.Name; pluginMigrationService.Add(pluginMigration); rockContext.SaveChanges(); result = true; } catch (Exception ex) { if (transactionActive) { sqlTxn.Rollback(); } throw new RockStartupException($"##Plugin Migration error occurred in { migrationNumber}, {migrationType.Name}##", ex); } } } } } catch (RockStartupException rockStartupException) { // if a plugin migration got an error, it gets wrapped with a RockStartupException // If this occurs, we'll log the migration that occurred, and stop running migrations for this assembly System.Diagnostics.Debug.WriteLine(rockStartupException.Message); LogError(rockStartupException, null); } catch (Exception ex) { // If an exception occurs in an an assembly, log the error, and stop running migrations for this assembly var startupException = new RockStartupException($"Error running migrations from {pluginAssemblyName}"); System.Diagnostics.Debug.WriteLine(startupException.Message); LogError(ex, null); } return(result); }
/// <summary> /// Migrates the plugins. /// </summary> /// <param name="rockContext">The rock context.</param> /// <returns></returns> /// <exception cref="System.Exception"> /// Could not connect to the SQL database! Please check the 'RockContext' connection string in the web.ConnectionString.config file. /// or /// </exception> public bool MigratePlugins(RockContext rockContext) { bool result = false; // Migrate any plugins that have pending migrations List <Type> migrationList = Rock.Reflection.FindTypes(typeof(Migration)).Select(a => a.Value).ToList(); // If any plugin migrations types were found if (migrationList.Any()) { // Create EF service for plugin migrations var pluginMigrationService = new PluginMigrationService(rockContext); // Get the current rock version var rockVersion = new Version(Rock.VersionInfo.VersionInfo.GetRockProductVersionNumber()); // Create dictionary for holding migrations specific to an assembly var assemblies = new Dictionary <string, Dictionary <int, Type> >(); // Iterate plugin migrations foreach (var migrationType in migrationList) { // Get the MigrationNumberAttribute for the migration var migrationNumberAttr = System.Attribute.GetCustomAttribute(migrationType, typeof(MigrationNumberAttribute)) as MigrationNumberAttribute; if (migrationNumberAttr != null) { // If the migration's minimum Rock version is less than or equal to the current rock version, add it to the list var minRockVersion = new Version(migrationNumberAttr.MinimumRockVersion); if (minRockVersion.CompareTo(rockVersion) <= 0) { string assemblyName = migrationType.Assembly.GetName().Name; if (!assemblies.ContainsKey(assemblyName)) { assemblies.Add(assemblyName, new Dictionary <int, Type>()); } // Check to make sure no another migration has same number if (assemblies[assemblyName].ContainsKey(migrationNumberAttr.Number)) { throw new Exception(string.Format("The '{0}' plugin assembly contains duplicate migration numbers ({1}).", assemblyName, migrationNumberAttr.Number)); } assemblies[assemblyName].Add(migrationNumberAttr.Number, migrationType); } } } var configConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["RockContext"]; if (configConnectionString != null) { string connectionString = configConnectionString.ConnectionString; if (!string.IsNullOrWhiteSpace(connectionString)) { using (SqlConnection con = new SqlConnection(connectionString)) { try { con.Open(); } catch (SqlException ex) { throw new Exception("Could not connect to the SQL database! Please check the 'RockContext' connection string in the web.ConnectionString.config file.", ex); } // Iterate each assembly that contains plugin migrations foreach (var assemblyMigrations in assemblies) { try { // Get the versions that have already been installed var installedVersions = pluginMigrationService.Queryable() .Where(m => m.PluginAssemblyName == assemblyMigrations.Key) .ToList(); // Iterate each migration in the assembly in MigrationNumber order foreach (var migrationType in assemblyMigrations.Value.OrderBy(t => t.Key)) { // Check to make sure migration has not already been run if (!installedVersions.Any(v => v.MigrationNumber == migrationType.Key)) { using (var sqlTxn = con.BeginTransaction()) { bool transactionActive = true; try { // Create an instance of the migration and run the up migration var migration = Activator.CreateInstance(migrationType.Value) as Rock.Plugin.Migration; migration.SqlConnection = con; migration.SqlTransaction = sqlTxn; migration.Up(); sqlTxn.Commit(); transactionActive = false; // Save the plugin migration version so that it is not run again var pluginMigration = new PluginMigration(); pluginMigration.PluginAssemblyName = assemblyMigrations.Key; pluginMigration.MigrationNumber = migrationType.Key; pluginMigration.MigrationName = migrationType.Value.Name; pluginMigrationService.Add(pluginMigration); rockContext.SaveChanges(); result = true; } catch (Exception ex) { if (transactionActive) { sqlTxn.Rollback(); } throw new Exception(string.Format("Plugin Migration error occurred in {0}, {1}", assemblyMigrations.Key, migrationType.Value.Name), ex); } } } } } catch (Exception ex) { // If an exception occurs in an an assembly, log the error, and continue with next assembly LogError(ex, null); } } } } } } return(result); }
/// <summary> /// Migrates the database. /// </summary> /// <returns>True if at least one migration was run</returns> public bool MigrateDatabase( RockContext rockContext ) { bool result = false; var fileInfo = new FileInfo( Server.MapPath( "~/App_Data/Run.Migration" ) ); if ( fileInfo.Exists ) { Database.SetInitializer( new MigrateDatabaseToLatestVersion<Rock.Data.RockContext, Rock.Migrations.Configuration>() ); // explictly check if the database exists, and force create it if doesn't exist if ( !rockContext.Database.Exists() ) { // If database did not exist, initialize a database (which runs existing Rock migrations) rockContext.Database.Initialize( true ); result = true; } else { // If database does exist, run any pending Rock migrations var migrator = new System.Data.Entity.Migrations.DbMigrator( new Rock.Migrations.Configuration() ); if ( migrator.GetPendingMigrations().Any() ) { migrator.Update(); result = true; } } fileInfo.Delete(); } else { // default Initializer is CreateDatabaseIfNotExists, but we don't want that to happen if automigrate is false, so set it to NULL so that nothing happens Database.SetInitializer<Rock.Data.RockContext>( null ); } // Migrate any plugins that have pending migrations List<Type> migrationList = Rock.Reflection.FindTypes( typeof( Migration ) ).Select( a => a.Value ).ToList(); // If any plugin migrations types were found if ( migrationList.Any() ) { // Create EF service for plugin migrations var pluginMigrationService = new PluginMigrationService( rockContext ); // Get the current rock version var rockVersion = new Version( Rock.VersionInfo.VersionInfo.GetRockProductVersionNumber() ); // Create dictionary for holding migrations specific to an assembly var assemblies = new Dictionary<string, Dictionary<int, Type>>(); // Iterate plugin migrations foreach ( var migrationType in migrationList ) { // Get the MigrationNumberAttribute for the migration var migrationNumberAttr = System.Attribute.GetCustomAttribute( migrationType, typeof( MigrationNumberAttribute ) ) as MigrationNumberAttribute; if ( migrationNumberAttr != null ) { // If the migration's minimum Rock version is less than or equal to the current rock version, add it to the list var minRockVersion = new Version( migrationNumberAttr.MinimumRockVersion ); if ( minRockVersion.CompareTo( rockVersion ) <= 0 ) { string assemblyName = migrationType.Assembly.GetName().Name; if ( !assemblies.ContainsKey( assemblyName ) ) { assemblies.Add( assemblyName, new Dictionary<int, Type>() ); } assemblies[assemblyName].Add( migrationNumberAttr.Number, migrationType ); } } } var configConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["RockContext"]; if ( configConnectionString != null ) { string connectionString = configConnectionString.ConnectionString; if ( !string.IsNullOrWhiteSpace( connectionString ) ) { using ( SqlConnection con = new SqlConnection( connectionString ) ) { con.Open(); // Iterate each assembly that contains plugin migrations foreach ( var assemblyMigrations in assemblies ) { try { // Get the versions that have already been installed var installedVersions = pluginMigrationService.Queryable() .Where( m => m.PluginAssemblyName == assemblyMigrations.Key ) .ToList(); // Iterate each migration in the assembly in MigrationNumber order foreach ( var migrationType in assemblyMigrations.Value.OrderBy( t => t.Key ) ) { // Check to make sure migration has not already been run if ( !installedVersions.Any( v => v.MigrationNumber == migrationType.Key ) ) { using ( var sqlTxn = con.BeginTransaction() ) { bool transactionActive = true; try { // Create an instance of the migration and run the up migration var migration = Activator.CreateInstance( migrationType.Value ) as Rock.Plugin.Migration; migration.SqlConnection = con; migration.SqlTransaction = sqlTxn; migration.Up(); sqlTxn.Commit(); transactionActive = false; // Save the plugin migration version so that it is not run again var pluginMigration = new PluginMigration(); pluginMigration.PluginAssemblyName = assemblyMigrations.Key; pluginMigration.MigrationNumber = migrationType.Key; pluginMigration.MigrationName = migrationType.Value.Name; pluginMigrationService.Add( pluginMigration ); rockContext.SaveChanges(); result = true; } catch ( Exception ex ) { if ( transactionActive ) { sqlTxn.Rollback(); } throw new Exception( string.Format( "Plugin Migration error occurred in {0}, {1}", assemblyMigrations.Key, migrationType.Value.Name ), ex ); } } } } } catch ( Exception ex ) { // If an exception occurs in an an assembly, log the error, and continue with next assembly LogError( ex, null ); } } } } } } return result; }
/// <summary> /// Migrates the plugins. /// </summary> /// <param name="rockContext">The rock context.</param> /// <returns></returns> /// <exception cref="System.Exception"> /// Could not connect to the SQL database! Please check the 'RockContext' connection string in the web.ConnectionString.config file. /// or /// </exception> public bool MigratePlugins( RockContext rockContext ) { bool result = false; // Migrate any plugins that have pending migrations List<Type> migrationList = Rock.Reflection.FindTypes( typeof( Migration ) ).Select( a => a.Value ).ToList(); // If any plugin migrations types were found if ( migrationList.Any() ) { // Create EF service for plugin migrations var pluginMigrationService = new PluginMigrationService( rockContext ); // Get the current rock version var rockVersion = new Version( Rock.VersionInfo.VersionInfo.GetRockProductVersionNumber() ); // Create dictionary for holding migrations specific to an assembly var assemblies = new Dictionary<string, Dictionary<int, Type>>(); // Iterate plugin migrations foreach ( var migrationType in migrationList ) { // Get the MigrationNumberAttribute for the migration var migrationNumberAttr = System.Attribute.GetCustomAttribute( migrationType, typeof( MigrationNumberAttribute ) ) as MigrationNumberAttribute; if ( migrationNumberAttr != null ) { // If the migration's minimum Rock version is less than or equal to the current rock version, add it to the list var minRockVersion = new Version( migrationNumberAttr.MinimumRockVersion ); if ( minRockVersion.CompareTo( rockVersion ) <= 0 ) { string assemblyName = migrationType.Assembly.GetName().Name; if ( !assemblies.ContainsKey( assemblyName ) ) { assemblies.Add( assemblyName, new Dictionary<int, Type>() ); } assemblies[assemblyName].Add( migrationNumberAttr.Number, migrationType ); } } } var configConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["RockContext"]; if ( configConnectionString != null ) { string connectionString = configConnectionString.ConnectionString; if ( !string.IsNullOrWhiteSpace( connectionString ) ) { using ( SqlConnection con = new SqlConnection( connectionString ) ) { try { con.Open(); } catch ( SqlException ex ) { throw new Exception( "Could not connect to the SQL database! Please check the 'RockContext' connection string in the web.ConnectionString.config file.", ex ); } // Iterate each assembly that contains plugin migrations foreach ( var assemblyMigrations in assemblies ) { try { // Get the versions that have already been installed var installedVersions = pluginMigrationService.Queryable() .Where( m => m.PluginAssemblyName == assemblyMigrations.Key ) .ToList(); // Iterate each migration in the assembly in MigrationNumber order foreach ( var migrationType in assemblyMigrations.Value.OrderBy( t => t.Key ) ) { // Check to make sure migration has not already been run if ( !installedVersions.Any( v => v.MigrationNumber == migrationType.Key ) ) { using ( var sqlTxn = con.BeginTransaction() ) { bool transactionActive = true; try { // Create an instance of the migration and run the up migration var migration = Activator.CreateInstance( migrationType.Value ) as Rock.Plugin.Migration; migration.SqlConnection = con; migration.SqlTransaction = sqlTxn; migration.Up(); sqlTxn.Commit(); transactionActive = false; // Save the plugin migration version so that it is not run again var pluginMigration = new PluginMigration(); pluginMigration.PluginAssemblyName = assemblyMigrations.Key; pluginMigration.MigrationNumber = migrationType.Key; pluginMigration.MigrationName = migrationType.Value.Name; pluginMigrationService.Add( pluginMigration ); rockContext.SaveChanges(); result = true; } catch ( Exception ex ) { if ( transactionActive ) { sqlTxn.Rollback(); } throw new Exception( string.Format( "Plugin Migration error occurred in {0}, {1}", assemblyMigrations.Key, migrationType.Value.Name ), ex ); } } } } } catch ( Exception ex ) { // If an exception occurs in an an assembly, log the error, and continue with next assembly LogError( ex, null ); } } } } } } return result; }
/// <summary> /// Migrates the database. /// </summary> public void MigrateDatabase() { // Check if database should be auto-migrated for the core and plugins if ( ConfigurationManager.AppSettings["AutoMigrateDatabase"].AsBoolean( true ) ) { try { Database.SetInitializer( new MigrateDatabaseToLatestVersion<Rock.Data.RockContext, Rock.Migrations.Configuration>() ); var rockContext = new RockContext(); // explictly check if the database exists, and force create it if doesn't exist if ( !rockContext.Database.Exists() ) { // If database did not exist, initialize a database (which runs existing Rock migrations) rockContext.Database.Initialize( true ); } else { // If database does exist, run any pending Rock migrations var migrator = new System.Data.Entity.Migrations.DbMigrator( new Rock.Migrations.Configuration() ); migrator.Update(); } // Migrate any plugins that have pending migrations List<Type> migrationList = Rock.Reflection.FindTypes( typeof( Migration ) ).Select( a => a.Value ).ToList(); // If any plugin migrations types were found if ( migrationList.Any() ) { // Create EF service for plugin migrations var pluginMigrationService = new PluginMigrationService( rockContext ); // Get the current rock version var rockVersion = new Version( Rock.VersionInfo.VersionInfo.GetRockProductVersionNumber() ); // Create dictionary for holding migrations specific to an assembly var assemblies = new Dictionary<string, Dictionary<int, Type>>(); // Iterate plugin migrations foreach ( var migrationType in migrationList ) { // Get the MigrationNumberAttribute for the migration var migrationNumberAttr = System.Attribute.GetCustomAttribute( migrationType, typeof( MigrationNumberAttribute ) ) as MigrationNumberAttribute; if ( migrationNumberAttr != null ) { // If the migration's minimum Rock version is less than or equal to the current rock version, add it to the list var minRockVersion = new Version( migrationNumberAttr.MinimumRockVersion ); if ( minRockVersion.CompareTo( rockVersion ) <= 0 ) { string assemblyName = migrationType.Assembly.GetName().Name; if ( !assemblies.ContainsKey( assemblyName ) ) { assemblies.Add( assemblyName, new Dictionary<int, Type>() ); } assemblies[assemblyName].Add( migrationNumberAttr.Number, migrationType ); } } } // Iterate each assembly that contains plugin migrations foreach ( var assemblyMigrations in assemblies ) { try { // Get the versions that have already been installed var installedVersions = pluginMigrationService.Queryable() .Where( m => m.PluginAssemblyName == assemblyMigrations.Key ) .ToList(); // Wrap the migrations for each assembly in a transaction so that if an error with one migration, none of the migrations are persisted RockTransactionScope.WrapTransaction( () => { // Iterate each migration in the assembly in MigrationNumber order foreach ( var migrationType in assemblyMigrations.Value.OrderBy( t => t.Key ) ) { // Check to make sure migration has not already been run if ( !installedVersions.Any( v => v.MigrationNumber == migrationType.Key ) ) { try { // Create an instance of the migration and run the up migration var migration = Activator.CreateInstance( migrationType.Value ) as Rock.Plugin.Migration; migration.Up(); // Save the plugin migration version so that it is not run again var pluginMigration = new PluginMigration(); pluginMigration.PluginAssemblyName = assemblyMigrations.Key; pluginMigration.MigrationNumber = migrationType.Key; pluginMigration.MigrationName = migrationType.Value.Name; pluginMigrationService.Add( pluginMigration ); rockContext.SaveChanges(); } catch ( Exception ex ) { throw new Exception( string.Format( "Plugin Migration error occurred in {0}, {1}", assemblyMigrations.Key, migrationType.Value.Name ), ex ); } } } } ); } catch ( Exception ex ) { // If an exception occurs in an an assembly, log the error, and continue with next assembly LogError( ex, null ); } } } } catch ( Exception ex ) { // if migrations fail, log error and attempt to continue LogError( ex, null ); } } else { // default Initializer is CreateDatabaseIfNotExists, but we don't want that to happen if automigrate is false, so set it to NULL so that nothing happens Database.SetInitializer<Rock.Data.RockContext>( null ); } }
/// <summary> /// Migrates the database. /// </summary> public void MigrateDatabase() { // Check if database should be auto-migrated for the core and plugins if (ConfigurationManager.AppSettings["AutoMigrateDatabase"].AsBoolean(true)) { try { Database.SetInitializer(new MigrateDatabaseToLatestVersion <Rock.Data.RockContext, Rock.Migrations.Configuration>()); var rockContext = new RockContext(); // explictly check if the database exists, and force create it if doesn't exist if (!rockContext.Database.Exists()) { // If database did not exist, initialize a database (which runs existing Rock migrations) rockContext.Database.Initialize(true); } else { // If database does exist, run any pending Rock migrations var migrator = new System.Data.Entity.Migrations.DbMigrator(new Rock.Migrations.Configuration()); migrator.Update(); } // Migrate any plugins that have pending migrations List <Type> migrationList = Rock.Reflection.FindTypes(typeof(Migration)).Select(a => a.Value).ToList(); // If any plugin migrations types were found if (migrationList.Any()) { // Create EF service for plugin migrations var pluginMigrationService = new PluginMigrationService(rockContext); // Get the current rock version var rockVersion = new Version(Rock.VersionInfo.VersionInfo.GetRockProductVersionNumber()); // Create dictionary for holding migrations specific to an assembly var assemblies = new Dictionary <string, Dictionary <int, Type> >(); // Iterate plugin migrations foreach (var migrationType in migrationList) { // Get the MigrationNumberAttribute for the migration var migrationNumberAttr = System.Attribute.GetCustomAttribute(migrationType, typeof(MigrationNumberAttribute)) as MigrationNumberAttribute; if (migrationNumberAttr != null) { // If the migration's minimum Rock version is less than or equal to the current rock version, add it to the list var minRockVersion = new Version(migrationNumberAttr.MinimumRockVersion); if (minRockVersion.CompareTo(rockVersion) <= 0) { string assemblyName = migrationType.Assembly.GetName().Name; if (!assemblies.ContainsKey(assemblyName)) { assemblies.Add(assemblyName, new Dictionary <int, Type>()); } assemblies[assemblyName].Add(migrationNumberAttr.Number, migrationType); } } } // Iterate each assembly that contains plugin migrations foreach (var assemblyMigrations in assemblies) { try { // Get the versions that have already been installed var installedVersions = pluginMigrationService.Queryable() .Where(m => m.PluginAssemblyName == assemblyMigrations.Key) .ToList(); // Wrap the migrations for each assembly in a transaction so that if an error with one migration, none of the migrations are persisted RockTransactionScope.WrapTransaction(() => { // Iterate each migration in the assembly in MigrationNumber order foreach (var migrationType in assemblyMigrations.Value.OrderBy(t => t.Key)) { // Check to make sure migration has not already been run if (!installedVersions.Any(v => v.MigrationNumber == migrationType.Key)) { try { // Create an instance of the migration and run the up migration var migration = Activator.CreateInstance(migrationType.Value) as Rock.Plugin.Migration; migration.Up(); // Save the plugin migration version so that it is not run again var pluginMigration = new PluginMigration(); pluginMigration.PluginAssemblyName = assemblyMigrations.Key; pluginMigration.MigrationNumber = migrationType.Key; pluginMigration.MigrationName = migrationType.Value.Name; pluginMigrationService.Add(pluginMigration); rockContext.SaveChanges(); } catch (Exception ex) { throw new Exception(string.Format("Plugin Migration error occurred in {0}, {1}", assemblyMigrations.Key, migrationType.Value.Name), ex); } } } }); } catch (Exception ex) { // If an exception occurs in an an assembly, log the error, and continue with next assembly LogError(ex, null); } } } } catch (Exception ex) { // if migrations fail, log error and attempt to continue LogError(ex, null); } } else { // default Initializer is CreateDatabaseIfNotExists, but we don't want that to happen if automigrate is false, so set it to NULL so that nothing happens Database.SetInitializer <Rock.Data.RockContext>(null); } }