Esempio n. 1
0
        protected virtual IReadOnlyList <SqlBatch> ApplyMigration([NotNull] Migration migration)
        {
            Check.NotNull(migration, nameof(migration));

            var migrationBuilder = new MigrationBuilder();

            migration.Up(migrationBuilder);

            var operations = migrationBuilder.Operations.ToList();

            operations.Add(_historyRepository.GetInsertOperation(new HistoryRow(migration.Id, ProductVersion)));

            var targetModel = _modelFactory.CreateModel(migration.BuildTargetModel);

            return(_migrationSqlGenerator.Generate(operations, targetModel));
        }
        public MigrationAssembly(
            [NotNull] DbContext context,
            [NotNull] IEntityOptions options,
            [NotNull] IMigrationModelFactory modelFactory)
        {
            Check.NotNull(context, nameof(context));
            Check.NotNull(options, nameof(options));
            Check.NotNull(modelFactory, nameof(modelFactory));

            var contextType = context.GetType();

            var assemblyName = RelationalOptionsExtension.Extract(options)?.MigrationsAssembly;
            var assembly     = assemblyName == null
                ? contextType.GetTypeInfo().Assembly
                : Assembly.Load(new AssemblyName(assemblyName));

            _migrations = new LazyRef <IReadOnlyList <Migration> >(
                () => GetMigrationTypes(assembly)
                .Where(t => TryGetContextType(t) == contextType)
                .Select(t => (Migration)Activator.CreateInstance(t.AsType()))
                .OrderBy(m => m.Id)
                .ToList());
            _modelSnapshot = new LazyRef <ModelSnapshot>(
                () => (
                    from t in GetTypes(assembly)
                    where t.IsSubclassOf(typeof(ModelSnapshot)) &&
                    TryGetContextType(t) == contextType
                    select(ModelSnapshot) Activator.CreateInstance(t.AsType()))
                .FirstOrDefault());
            _lastModel = new LazyRef <IModel>(
                () =>
            {
                if (_modelSnapshot.Value == null)
                {
                    return(null);
                }

                return(modelFactory.CreateModel(_modelSnapshot.Value.BuildModel));
            });
        }
        // TODO: DRY (file names)
        public virtual MigrationFiles RemoveMigration([NotNull] string projectDir, [NotNull] string rootNamespace)
        {
            Check.NotEmpty(projectDir, nameof(projectDir));
            Check.NotEmpty(rootNamespace, nameof(rootNamespace));

            var files = new MigrationFiles();

            var modelSnapshot = _migrationAssembly.ModelSnapshot;

            if (modelSnapshot == null)
            {
                throw new InvalidOperationException(Strings.NoSnapshot);
            }

            var lastModel = _migrationAssembly.LastModel;
            var language  = _migrationCodeGenerator.Language;

            IModel model      = null;
            var    migrations = _migrationAssembly.Migrations;

            if (migrations.Count != 0)
            {
                var migration = migrations.Last();
                model = _modelFactory.CreateModel(migration.BuildTargetModel);

                if (!_modelDiffer.HasDifferences(model, lastModel))
                {
                    if (_historyRepository.GetAppliedMigrations().Any(
                            e => e.MigrationId.Equals(migration.Id, StringComparison.OrdinalIgnoreCase)))
                    {
                        throw new InvalidOperationException(Strings.UnapplyMigration(migration.Id));
                    }

                    var migrationFileName = migration.Id + language;
                    var migrationFile     = TryGetProjectFile(projectDir, migrationFileName);
                    if (migrationFile != null)
                    {
                        _logger.Value.LogInformation(Strings.RemovingMigration(migration.Id));
                        // TODO: Test version control. If broken, delete and write files in the commands
                        File.Delete(migrationFile);
                        files.MigrationFile = migrationFile;
                    }
                    else
                    {
                        _logger.Value.LogWarning(Strings.NoMigrationFile(migrationFileName, migration.GetType().FullName));
                    }

                    var migrationMetadataFileName = migration.Id + ".Designer" + language;
                    var migrationMetadataFile     = TryGetProjectFile(projectDir, migrationMetadataFileName);
                    if (migrationMetadataFile != null)
                    {
                        File.Delete(migrationMetadataFile);
                        files.MigrationMetadataFile = migrationMetadataFile;
                    }
                    else
                    {
                        _logger.Value.LogVerbose(Strings.NoMigrationMetadataFile(migrationMetadataFileName));
                    }

                    model = migrations.Count > 1
                        ? _modelFactory.CreateModel(migrations[migrations.Count - 2].BuildTargetModel)
                        : null;
                }
                else
                {
                    _logger.Value.LogVerbose(Strings.ManuallyDeleted);
                }
            }

            var modelSnapshotName     = modelSnapshot.GetType().Name;
            var modelSnapshotFileName = modelSnapshotName + language;
            var modelSnapshotFile     = TryGetProjectFile(projectDir, modelSnapshotFileName);

            if (model == null)
            {
                if (modelSnapshotFile != null)
                {
                    _logger.Value.LogInformation(Strings.RemovingSnapshot);
                    File.Delete(modelSnapshotFile);
                    files.ModelSnapshotFile = modelSnapshotFile;
                }
                else
                {
                    _logger.Value.LogWarning(
                        Strings.NoSnapshotFile(modelSnapshotFileName, modelSnapshot.GetType().FullName));
                }
            }
            else
            {
                var modelSnapshotNamespace = modelSnapshot.GetType().Namespace;
                var modelSnapshotCode      = _migrationCodeGenerator.GenerateSnapshot(
                    modelSnapshotNamespace,
                    _contextType,
                    modelSnapshotName,
                    model);

                if (modelSnapshotFile == null)
                {
                    modelSnapshotFile = Path.Combine(
                        GetDirectory(projectDir, null, GetSubnamespace(rootNamespace, modelSnapshotNamespace)),
                        modelSnapshotFileName);
                }

                _logger.Value.LogInformation(Strings.RevertingSnapshot);
                File.WriteAllText(modelSnapshotFile, modelSnapshotCode);
            }

            return(files);
        }