首页 > 解决方案 > GetMigrations、GetAppliedMigrations 和 GetPendingMigrations 的框架等效项是什么?

问题描述

有一些 .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.");

}

标签: .netentity-frameworkentity-framework-6

解决方案


找到了解决方案!

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.");
        }
    }
}

推荐阅读