如何有效控制并管理Ef Core的数据库迁移过程?
摘要:Ef Core花里胡哨系列(8) 如何可控管理Ef Core的迁移? 通常使用Ef Core迁移时,可能就是简单的使用命令dotnet-ef migrations add或者dotnet ef database update等等,基本都需要
Ef Core花里胡哨系列(8) 如何可控管理Ef Core的迁移?
通常使用Ef Core迁移时,可能就是简单的使用命令dotnet-ef migrations add或者dotnet ef database update等等,基本都需要靠命令维护,非常的繁琐。特别是现在很多项目都是迭代型项目,很容易造成开发人员和运维人员的负担,所以,我们是否可以将其自动化?
自动迁移
自动迁移顾名思义,就是可以让程序启动的时候自己执行迁移,不需要运维人员参与,开发人员只需要保证迁移顺序的正确性即可。
自动建库
如果想使用首次自动建库,那我们就需要生成首次迁移时,直接删除首次迁移的文件,留下[Sample]DbContextModelSnapshot快照文件即可,当然,这些不是主要内容,只是用来引出下面的可控迁移。
var app = builder.Build();
await using var scoped = app.Services.CreateAsyncScope();
using var db = scoped.ServiceProvider.GetRequiredService<SampleDbContext>();
try
{
// db.Database.Migrate(); // 需要保留首次迁移文件,并且后续启动可以自动迁移
db.Database.EnsureCreated(); // 不需要保留首次迁移文件
}
catch
{
Console.WriteLine("init database error.");
}
可控迁移
可控迁移即我们可以通过封装Ef Core内置的各种Service来帮助我们实现控制迁移的效果。
EfMigrationHistory
我们要可控迁移,那么我们就需要想办法操控__EFMigrationsHistory这张表,它是Ef Core内置的表,用来记录迁移的记录,这张表是一张无状态的表,他只负责存储成功的迁移名称和迁移时Ef Core的版本,其它没有关联,我们如何管理它呢?我们只需在DbContext中创建一个同名的表即可,并且可以预先设计好其它审计用字段,后续不可更改。
例如我们重新设计这张表,除了迁移IdMigrationId和Ef Core的版本ProductVersion外,我们添加迁移应用时间,和迁移应用类型字段。
[Table("__EFMigrationsHistory")]
public class EFMigrationsHistory
{
[Key]
[MaxLength(150)]
public required string MigrationId { get; set; }
[MaxLength(32)]
public string ProductVersion { get; set; } = null!;
[NotMapped]
public string Sort => MigrationId.Split("_")[0];
[Comment("迁移时间")]
public DateTime? MigrationTime { get; set; } = DateTime.Now;
[Column(TypeName = "varchar(20)")]
public MigrationType MigrationType { get; set; } = MigrationType.Success;
}
添加迁移类型的目的是为了增加迁移执行顺序的丰富性,下面提供了成功Success、尝试但失败TryFail、尝试但成功TrySuccess以及跳过Skip等多种方式。其中History和Install为记录型,主要是为了标记历史记录和安装时间。
public enum MigrationType
{
Success,
TryFail,
TrySuccess,
Skip,
History,
Install
}
随后我们将其添加到DbContext上下文中即可,我们的新结构会替代原来的结构实行职能。
