拦截 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());
}
}
我正在尝试将 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());
}
}