// TODO: DRY (file names) public virtual MigrationFiles RemoveMigration([NotNull] string projectDir, [NotNull] string rootNamespace, bool force) { Check.NotEmpty(projectDir, nameof(projectDir)); Check.NotEmpty(rootNamespace, nameof(rootNamespace)); var files = new MigrationFiles(); var modelSnapshot = _migrationsAssembly.ModelSnapshot; if (modelSnapshot == null) { throw new InvalidOperationException(DesignCoreStrings.NoSnapshot); } var language = _migrationCodeGenerator.FileExtension; IModel model = null; var migrations = _migrationsAssembly.Migrations .Select(m => _migrationsAssembly.CreateMigration(m.Value, _activeProvider)) .ToList(); if (migrations.Count != 0) { var migration = migrations[migrations.Count - 1]; model = migration.TargetModel; if (!_modelDiffer.HasDifferences(model, modelSnapshot.Model)) { if (force) { _logger.Value.LogWarning(DesignCoreStrings.ForceRemoveMigration(migration.GetId())); } else if (_historyRepository.GetAppliedMigrations().Any( e => e.MigrationId.Equals(migration.GetId(), StringComparison.OrdinalIgnoreCase))) { throw new InvalidOperationException(DesignCoreStrings.UnapplyMigration(migration.GetId())); } var migrationFileName = migration.GetId() + language; var migrationFile = TryGetProjectFile(projectDir, migrationFileName); if (migrationFile != null) { _logger.Value.LogInformation(DesignCoreStrings.RemovingMigration(migration.GetId())); File.Delete(migrationFile); files.MigrationFile = migrationFile; } else { _logger.Value.LogWarning( DesignCoreStrings.NoMigrationFile(migrationFileName, migration.GetType().ShortDisplayName())); } var migrationMetadataFileName = migration.GetId() + ".Designer" + language; var migrationMetadataFile = TryGetProjectFile(projectDir, migrationMetadataFileName); if (migrationMetadataFile != null) { File.Delete(migrationMetadataFile); files.MetadataFile = migrationMetadataFile; } else { _logger.Value.LogDebug(DesignCoreStrings.NoMigrationMetadataFile(migrationMetadataFileName)); } model = migrations.Count > 1 ? migrations[migrations.Count - 2].TargetModel : null; } else { _logger.Value.LogDebug(DesignCoreStrings.ManuallyDeleted); } } var modelSnapshotName = modelSnapshot.GetType().Name; var modelSnapshotFileName = modelSnapshotName + language; var modelSnapshotFile = TryGetProjectFile(projectDir, modelSnapshotFileName); if (model == null) { if (modelSnapshotFile != null) { _logger.Value.LogInformation(DesignCoreStrings.RemovingSnapshot); File.Delete(modelSnapshotFile); files.SnapshotFile = modelSnapshotFile; } else { _logger.Value.LogWarning( DesignCoreStrings.NoSnapshotFile(modelSnapshotFileName, modelSnapshot.GetType().ShortDisplayName())); } } else { var modelSnapshotNamespace = modelSnapshot.GetType().Namespace; Debug.Assert(!string.IsNullOrEmpty(modelSnapshotNamespace)); var modelSnapshotCode = _migrationCodeGenerator.GenerateSnapshot( modelSnapshotNamespace, _contextType, modelSnapshotName, model); if (modelSnapshotFile == null) { modelSnapshotFile = Path.Combine( GetDirectory(projectDir, null, GetSubNamespace(rootNamespace, modelSnapshotNamespace)), modelSnapshotFileName); } _logger.Value.LogInformation(DesignCoreStrings.RevertingSnapshot); File.WriteAllText(modelSnapshotFile, modelSnapshotCode, Encoding.UTF8); } return(files); }