public virtual ScaffoldedMigration ScaffoldMigration(
            [NotNull] string migrationName,
            [NotNull] string rootNamespace)
        {
            Check.NotEmpty(migrationName, nameof(migrationName));
            Check.NotEmpty(rootNamespace, nameof(rootNamespace));

            if (_migrationAssembly.Migrations.Any(
                    m => _idGenerator.GetName(m.Id).Equals(migrationName, StringComparison.OrdinalIgnoreCase)))
            {
                throw new InvalidOperationException(Strings.DuplicateMigrationName(migrationName));
            }

            var lastMigration      = _migrationAssembly.Migrations.LastOrDefault();
            var migrationNamespace = lastMigration?.GetType().Namespace ?? rootNamespace + ".Migrations";
            var modelSnapshot      = _migrationAssembly.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.CreateId(migrationName);
            var modelSnapshotNamespace = modelSnapshot?.GetType().Namespace ?? migrationNamespace;
            var modelSnapshotName      = modelSnapshot?.GetType().Name ?? _contextType.Name + "ModelSnapshot";

            var migrationCode = _migrationCodeGenerator.Generate(
                migrationNamespace,
                migrationName,
                upOperations,
                downOperations);
            var migrationMetadataCode = _migrationCodeGenerator.GenerateMetadata(
                migrationNamespace,
                _contextType,
                migrationName,
                migrationId,
                ProductVersion,
                _model);
            var modelSnapshotCode = _migrationCodeGenerator.GenerateSnapshot(
                modelSnapshotNamespace,
                _contextType,
                modelSnapshotName,
                _model);

            return(new ScaffoldedMigration(
                       _migrationCodeGenerator.Language,
                       lastMigration?.Id,
                       migrationCode,
                       migrationId,
                       migrationMetadataCode,
                       GetSubnamespace(rootNamespace, migrationNamespace),
                       modelSnapshotCode,
                       modelSnapshotName,
                       GetSubnamespace(rootNamespace, modelSnapshotNamespace)));
        }
        public virtual ScaffoldedMigration ScaffoldMigration(
            [NotNull] string migrationName,
            [NotNull] string rootNamespace)
        {
            Check.NotEmpty(migrationName, nameof(migrationName));
            Check.NotEmpty(rootNamespace, nameof(rootNamespace));

            if (_migrationsAssembly.FindMigration(migrationName) != null)
            {
                throw new InvalidOperationException(Strings.DuplicateMigrationName(migrationName));
            }

            var lastMigration      = _migrationsAssembly.Migrations.LastOrDefault();
            var migrationNamespace = GetNamespace(lastMigration?.GetType(), rootNamespace + ".Migrations");
            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 = _contextType.Name + "ModelSnapshot";

            if (modelSnapshot != null)
            {
                var lastModelSnapshotName = modelSnapshot.GetType().Name;
                if (lastModelSnapshotName != modelSnapshotName)
                {
                    _logger.Value.LogVerbose(Strings.ReusingSnapshotName(lastModelSnapshotName));

                    modelSnapshotName = lastModelSnapshotName;
                }
            }

            if (upOperations.Any(o => o.IsDestructiveChange))
            {
                _logger.Value.LogWarning(Strings.DestructiveOperation);
            }

            var migrationCode = _migrationCodeGenerator.Generate(
                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.Language,
                       lastMigration?.Id,
                       migrationCode,
                       migrationId,
                       migrationMetadataCode,
                       GetSubnamespace(rootNamespace, migrationNamespace),
                       modelSnapshotCode,
                       modelSnapshotName,
                       GetSubnamespace(rootNamespace, modelSnapshotNamespace)));
        }