예제 #1
0
        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 InvalidOperationException(DesignCoreStrings.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.Value.LogWarning(DesignCoreStrings.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.Value.LogDebug(DesignCoreStrings.ReusingSnapshotName(lastModelSnapshotName));

                    modelSnapshotName = lastModelSnapshotName;
                }
            }

            if (upOperations.Any(o => o.IsDestructiveChange))
            {
                _logger.Value.LogWarning(DesignCoreStrings.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)));
        }