Что такое каркасный эквивалент GetMigrations, GetAppliedMigrations и GetPendingMigrations? - PullRequest
0 голосов
/ 01 ноября 2019

Существует несколько методов .Net Core, которые возвращают миграции, ожидающие миграции и примененные миграции. Я искал везде, чтобы найти эквивалентные методы для Entity Framework 6, и они оказались пустыми.

Методы:

database.GetMigrations();
database.GetAppliedMigrations();
database.GetPendingMigrations();

Мне нужны эти методы, поэтому яможет запустить метод защиты для защиты базы данных от странных миграций:

/// <summary>
/// This function performs two checks to ensure the database is migrated in a safe manner.
/// 1) Checks that all applied migrations exist in the assembly
///    An applied migration may be missing if a migration from a different git branch was applied, but that migration
///    has not been merged into the current git branch.
///    Before proceeding, merge the git branch containing the other migration, or checkout the other git branch and rollback the migration.
/// 2) Checks that pending migrations will be applied chronologically after applied migrations
///    A migration may be applied out of chronological order when switching to a git branch with a pending migration that has an earlier timestamp.
///    Before proceeding, either, remove the migration and recreate it with an updated timestamp, or, rollback the database to a previous migration
///    and then apply the migrations in order.
/// </summary>
/// <param name="database"></param>
public static void ProtectDatabaseFromCorruption(Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade database)
{
    //Check that all applied migrations exist in the assembly
    var assemblyMigrations = database.GetMigrations();
    var appliedMigrations = database.GetAppliedMigrations();
    var pendingMigrations = database.GetPendingMigrations();
    if (appliedMigrations.Any(a => !assemblyMigrations.Contains(a)))
        throw new Exception("There are applied migrations that do not exist in this assembly. All applied migrations must exist in the assembly. Aborting the migration.");

    // Check that pending migrations will be applied chronologically after applied migrations
    var appliedTimestamps = appliedMigrations.Select(m => Convert.ToUInt64(m.Substring(0, 14)));
    var pendingTimestamps = pendingMigrations.Select(m => Convert.ToUInt64(m.Substring(0, 14)));
    if (appliedTimestamps.Any(a => pendingTimestamps.Any(p => a > p)))
        throw new Exception("There are pending migrations with a timestamp earlier than the timestamps of one or more applied migrations. Migrations must be applied chronologically. Aborting the migration.");

}

1 Ответ

0 голосов
/ 01 ноября 2019

Нашли решение!

namespace MyProject.Migrations
{
    using System;
    using System.Data.Entity.Migrations;
    using System.Linq;

    internal sealed class Configuration : DbMigrationsConfiguration<MyProject.Entities>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = false;

            ProtectDatabaseFromCorruption();
        }

        public void ProtectDatabaseFromCorruption()
        {
            var migrator = new DbMigrator(this);

            var assemblyMigrations = migrator.GetLocalMigrations();
            var appliedMigrations = migrator.GetDatabaseMigrations();
            var pendingMigrations = migrator.GetPendingMigrations();

            Console.WriteLine($"Migrations in assembly: {assemblyMigrations.Count()}");
            Console.WriteLine($"Migrations applied to db: {appliedMigrations.Count()}");
            Console.WriteLine($"Migrations pending: {pendingMigrations.Count()}");

            //Check that all applied migrations exist in the assembly
            if (appliedMigrations.Any(a => !assemblyMigrations.Contains(a)))
                throw new Exception("There are applied migrations that do not exist in this assembly. All applied migrations must exist in the assembly. Aborting the migration.");

            // Check that pending migrations will be applied chronologically after applied migrations
            var appliedTimestamps = appliedMigrations.Select(m => Convert.ToUInt64(m.Substring(0, 14)));
            var pendingTimestamps = pendingMigrations.Select(m => Convert.ToUInt64(m.Substring(0, 14)));
            if (appliedTimestamps.Any(a => pendingTimestamps.Any(p => a > p)))
                throw new Exception("There are pending migrations with a timestamp earlier than the timestamps of one or more applied migrations. Migrations must be applied chronologically. Aborting the migration.");
        }
    }
}
...