/// <summary> /// Scaffolds a new migration. /// </summary> /// <param name="migrationName">The migration's name.</param> /// <param name="rootNamespace"> /// The project's root namespace, <see langword="null" /> to indicate no automatic /// namespace generation, just use sub-namespace as is. /// </param> /// <param name="subNamespace"> /// The migration's sub-namespace. Note: the root-namespace and /// the sub-namespace should not both be empty. /// </param> /// <param name="language">The project's language.</param> /// <returns>The scaffolded migration.</returns> public virtual ScaffoldedMigration ScaffoldMigration( string migrationName, string?rootNamespace, string?subNamespace = null, string?language = null) { if (Dependencies.MigrationsAssembly.FindMigrationId(migrationName) != null) { throw new OperationException(DesignStrings.DuplicateMigrationName(migrationName)); } var overrideNamespace = rootNamespace == null; var subNamespaceDefaulted = false; if (string.IsNullOrEmpty(subNamespace) && !overrideNamespace) { subNamespaceDefaulted = true; subNamespace = "Migrations"; } var(key, typeInfo) = Dependencies.MigrationsAssembly.Migrations.LastOrDefault(); var migrationNamespace = (!string.IsNullOrEmpty(rootNamespace) && !string.IsNullOrEmpty(subNamespace)) ? rootNamespace + "." + subNamespace : !string.IsNullOrEmpty(rootNamespace) ? rootNamespace : subNamespace; if (subNamespaceDefaulted) { migrationNamespace = GetNamespace(typeInfo?.AsType(), migrationNamespace !); } var sanitizedContextName = _contextType.Name; var genericMarkIndex = sanitizedContextName.IndexOf('`'); if (genericMarkIndex != -1) { sanitizedContextName = sanitizedContextName[..genericMarkIndex];
/// <summary> /// Scaffolds a new migration. /// </summary> /// <param name="migrationName"> The migration's name. </param> /// <param name="rootNamespace"> /// The project's root namespace, <c>null</c> to indicate no automatic /// namespace generation, just use sub-namespace as is. /// </param> /// <param name="subNamespace"> /// The migration's sub-namespace. Note: the root-namespace and /// the sub-namespace should not both be empty. /// </param> /// <param name="language"> The project's language. </param> /// <returns> The scaffolded migration. </returns> public virtual ScaffoldedMigration ScaffoldMigration( string migrationName, string rootNamespace, string subNamespace = null, string language = null) { Check.NotEmpty(migrationName, nameof(migrationName)); if (Dependencies.MigrationsAssembly.FindMigrationId(migrationName) != null) { throw new OperationException(DesignStrings.DuplicateMigrationName(migrationName)); } var overrideNamespace = rootNamespace == null; var subNamespaceDefaulted = false; if (string.IsNullOrEmpty(subNamespace) && !overrideNamespace) { subNamespaceDefaulted = true; subNamespace = "Migrations"; } var lastMigration = Dependencies.MigrationsAssembly.Migrations.LastOrDefault(); var migrationNamespace = (!string.IsNullOrEmpty(rootNamespace) && !string.IsNullOrEmpty(subNamespace)) ? rootNamespace + "." + subNamespace : !string.IsNullOrEmpty(rootNamespace) ? rootNamespace : subNamespace; if (subNamespaceDefaulted) { migrationNamespace = GetNamespace(lastMigration.Value?.AsType(), migrationNamespace); } var sanitizedContextName = _contextType.Name; var genericMarkIndex = sanitizedContextName.IndexOf('`'); if (genericMarkIndex != -1) { sanitizedContextName = sanitizedContextName.Substring(0, genericMarkIndex); } if (ContainsForeignMigrations(migrationNamespace)) { if (subNamespaceDefaulted) { var builder = new StringBuilder(); if (!string.IsNullOrEmpty(rootNamespace)) { builder.Append(rootNamespace); builder.Append("."); } builder.Append("Migrations."); if (sanitizedContextName.EndsWith("Context", StringComparison.Ordinal)) { builder.Append(sanitizedContextName, 0, sanitizedContextName.Length - 7); } else { builder .Append(sanitizedContextName) .Append("Migrations"); } migrationNamespace = builder.ToString(); } else { Dependencies.OperationReporter.WriteWarning(DesignStrings.ForeignMigrations(migrationNamespace)); } } var modelSnapshot = Dependencies.MigrationsAssembly.ModelSnapshot; var lastModel = Dependencies.SnapshotModelProcessor.Process(modelSnapshot?.Model)?.GetRelationalModel(); var upOperations = Dependencies.MigrationsModelDiffer .GetDifferences(lastModel, Dependencies.Model.GetRelationalModel()); var downOperations = upOperations.Count > 0 ? Dependencies.MigrationsModelDiffer.GetDifferences(Dependencies.Model.GetRelationalModel(), lastModel) : new List <MigrationOperation>(); var migrationId = Dependencies.MigrationsIdGenerator.GenerateId(migrationName); var modelSnapshotNamespace = overrideNamespace ? migrationNamespace : GetNamespace(modelSnapshot?.GetType(), migrationNamespace); var modelSnapshotName = sanitizedContextName + "ModelSnapshot"; if (modelSnapshot != null) { var lastModelSnapshotName = modelSnapshot.GetType().Name; if (lastModelSnapshotName != modelSnapshotName) { Dependencies.OperationReporter.WriteVerbose(DesignStrings.ReusingSnapshotName(lastModelSnapshotName)); modelSnapshotName = lastModelSnapshotName; } } if (upOperations.Any(o => o.IsDestructiveChange)) { Dependencies.OperationReporter.WriteWarning(DesignStrings.DestructiveOperation); } var codeGenerator = Dependencies.MigrationsCodeGeneratorSelector.Select(language); var migrationCode = codeGenerator.GenerateMigration( migrationNamespace, migrationName, upOperations, downOperations); var migrationMetadataCode = codeGenerator.GenerateMetadata( migrationNamespace, _contextType, migrationName, migrationId, Dependencies.Model); var modelSnapshotCode = codeGenerator.GenerateSnapshot( modelSnapshotNamespace, _contextType, modelSnapshotName, Dependencies.Model); return(new ScaffoldedMigration( codeGenerator.FileExtension, lastMigration.Key, migrationCode, migrationId, migrationMetadataCode, GetSubNamespace(rootNamespace, migrationNamespace), modelSnapshotCode, modelSnapshotName, GetSubNamespace(rootNamespace, modelSnapshotNamespace))); }
public virtual ScaffoldedMigration ScaffoldMigration( [NotNull] string migrationName, [NotNull] string rootNamespace, [CanBeNull] string subNamespace = null) { Check.NotEmpty(migrationName, nameof(migrationName)); Check.NotEmpty(rootNamespace, nameof(rootNamespace)); if (_migrationsAssembly.FindMigrationId(migrationName) != null) { throw new OperationException(DesignStrings.DuplicateMigrationName(migrationName)); } var subNamespaceDefaulted = false; if (string.IsNullOrEmpty(subNamespace)) { subNamespaceDefaulted = true; subNamespace = "Migrations"; } var lastMigration = _migrationsAssembly.Migrations.LastOrDefault(); var migrationNamespace = rootNamespace + "." + subNamespace; if (subNamespaceDefaulted) { migrationNamespace = GetNamespace(lastMigration.Value?.AsType(), migrationNamespace); } var sanitizedContextName = _contextType.Name; var genericMarkIndex = sanitizedContextName.IndexOf('`'); if (genericMarkIndex != -1) { sanitizedContextName = sanitizedContextName.Substring(0, genericMarkIndex); } if (ContainsForeignMigrations(migrationNamespace)) { if (subNamespaceDefaulted) { var builder = new StringBuilder() .Append(rootNamespace) .Append(".Migrations."); if (sanitizedContextName.EndsWith("Context", StringComparison.Ordinal)) { builder.Append(sanitizedContextName.Substring(0, sanitizedContextName.Length - 7)); } else { builder .Append(sanitizedContextName) .Append("Migrations"); } migrationNamespace = builder.ToString(); } else { _logger.LogWarning( DesignEventId.ForeignMigrations, () => DesignStrings.ForeignMigrations(migrationNamespace)); } } var modelSnapshot = _migrationsAssembly.ModelSnapshot; var lastModel = modelSnapshot?.Model; var upOperations = _modelDiffer.GetDifferences(lastModel, _model); var downOperations = upOperations.Any() ? _modelDiffer.GetDifferences(_model, lastModel) : new List <MigrationOperation>(); var migrationId = _idGenerator.GenerateId(migrationName); var modelSnapshotNamespace = GetNamespace(modelSnapshot?.GetType(), migrationNamespace); var modelSnapshotName = sanitizedContextName + "ModelSnapshot"; if (modelSnapshot != null) { var lastModelSnapshotName = modelSnapshot.GetType().Name; if (lastModelSnapshotName != modelSnapshotName) { _logger.LogDebug( DesignEventId.ReusingSnapshotName, () => DesignStrings.ReusingSnapshotName(lastModelSnapshotName)); modelSnapshotName = lastModelSnapshotName; } } if (upOperations.Any(o => o.IsDestructiveChange)) { _logger.LogWarning( DesignEventId.DestructiveOperation, () => DesignStrings.DestructiveOperation); } var migrationCode = _migrationCodeGenerator.GenerateMigration( migrationNamespace, migrationName, upOperations, downOperations); var migrationMetadataCode = _migrationCodeGenerator.GenerateMetadata( migrationNamespace, _contextType, migrationName, migrationId, _model); var modelSnapshotCode = _migrationCodeGenerator.GenerateSnapshot( modelSnapshotNamespace, _contextType, modelSnapshotName, _model); return(new ScaffoldedMigration( _migrationCodeGenerator.FileExtension, lastMigration.Key, migrationCode, migrationId, migrationMetadataCode, GetSubNamespace(rootNamespace, migrationNamespace), modelSnapshotCode, modelSnapshotName, GetSubNamespace(rootNamespace, modelSnapshotNamespace))); }