拦截 SqlServerMigrationsSqlGenerator 以防止某些表的迁移?

Intercepting SqlServerMigrationsSqlGenerator to prevent migration of certain tables?

我正在尝试将 EF Core 3.0 迁移与现有表和首先使用代码构建的新表混合使用。为了防止现有表的脚手架,我想用属性(流利或注释)装饰模型 class 以便跳过这些表的迁移代码生成,但模型仍然内置在 DbContext class.

我采用的方法是将以下几行添加到 OnConfiguring

optionsBuilder.ReplaceService<IMigrationsSqlGenerator, SkipMigrator>();

然后使用以下代码创建 SkipMigrator

public class SkipMigrator:SqlServerMigrationsSqlGenerator
{
    public SkipMigrator(
        MigrationsSqlGeneratorDependencies dependencies,
    IMigrationsAnnotationProvider migrationsAnnotations)
    : base(dependencies, migrationsAnnotations){}

    protected override void Generate(
        MigrationOperation operation,
        IModel model,
        MigrationCommandListBuilder builder)
    {
        if (operation.FindAnnotation("SkipMigrations")!=null)
        {
            Console.WriteLine("Skipping table:");
        }
        else
        {
            base.Generate(operation,model,builder);
        }
    }
}

我假设 Generate 方法触发了迁移代码文件的创建,但它从未被调用。我应该在其他地方拦截代码生成吗?

是否有 different/simpler 方法告诉迁移跳过表但仍将它们保留在我的 DbContext 中?

If there a different/simpler way to tell migrations to skip tables yet still keep them in my DbContext?

是的,但这需要不同的方法。

与其使用当前的 DbContext class 创建迁移,不如创建仅用于创建迁移的 SecondDbContext class。这个新的 SecondDbContext class 将保存您希望 EF 在其上执行迁移的 DbSets<T>

然后在调用add-migration UpdateTable -c SecondDbContext然后update-database -c SecondDbContext时简单地指定第二个上下文。

您尝试创建自己的 IMigrationsSqlGenerator 的方法是正确的,我之前使用过这种方法来更改作为迁移的一部分生成的 SQL。

            services.AddDbContext<MyDbContext>(opt =>
            {
                opt.UseSqlServer();
                opt.ReplaceService<IMigrationsSqlGenerator, SkipMigrator>();
            });

但是,从 EF Core 5.0 开始,使用 TableBuilder:

上的 ExcludeFromMigrations() 方法可以更轻松地从迁移中排除特定表
public class ReportingContext : DbContext
{
    public DbSet<User> Users { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>().ToTable(nameof(Users), t => t.ExcludeFromMigrations());
    }
}

更多信息:https://devblogs.microsoft.com/dotnet/announcing-entity-framework-core-efcore-5-0-rc1/#exclude-tables-from-migrations