EF Core使用单独的项目管理迁移
前言
EF Core的迁移可以很方便的管理项目数据库的结构的升级和回退,但是把迁移和业务代码放在一起显得不是那么优雅,于是我将生成的迁移放在单独的类库项目中,这样使用不同的类库还能对不同环境的迁移分开管理。
参考了以下资源:
EntityFrameworkCore数据迁移(一) - 没有星星的夏季 - 博客园 (cnblogs.com)
使用单独的迁移项目-EF Core | Microsoft Docs
本文章所用示例代码:
FFFirer/EFCoreMigrationsDemo (github.com)
项目介绍
在如下所示项目结构中,EFCoreMigrationsDemo.Domain(类库)项目中存放实体类以及实体上下文,我称之为DbContext项目,EFCoreMigrationsDemo.Web中主要是用来使用DbContext的项目,这里称之为MVC项目,EFCoreMigrationsDemo.EFCoreMigrations(类库)项目就是要生成迁移的项目,将在这个项目中管理迁移,我称之为迁移项目。
准备工作
首先在DbContext中准备实体和一个DbContext
User.cs
public class User { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } public DateTime CreatedTime { get; set; } }
DemoContext.cs
public class DemoContext : DbContext { public DemoContext(DbContextOptions<DemoContext> options) : base(options) { } public DbSet<User> Users { get; set; } }
在MVC中注入DemoContext
services.AddDbContext<DemoContext>(options => { options.UseSqlServer(Configuration.GetConnectionString("SqlServer")); });
迁移
迁移项目需要引用DbContext项目,应用迁移需要迁移项目引用以下nuget包
Microsoft.EntityFrameworkCore.Tools
添加迁移数据上下文,继承自DbContext项目的上下文,这样既保留了所有原有DbContext的上下文,在迁移上下文的改动又不会影响到原来的DbContext
public class MigrationContext : DemoContext { public MigrationContext(DbContextOptions<DemoContext> options) : base(options) { } }
添加一个迁移上下文的工厂类,需要实现接口IDesignTimeDbContextFactory<MigrationContext>
public class MigrationContextFactory : IDesignTimeDbContextFactory<MigrationContext> { public MigrationContext CreateDbContext(string[] args) { var builder = new DbContextOptionsBuilder<DemoContext>() .UseSqlServer("Data Source=;Initial Catalog=;Persist Security Info=True;User ID=;Password="); return new MigrationContext(builder.Options); } }
然后打开PM管理控制台或命令行窗口,进入到迁移项目的文件目录下
以dotnet core tool工具为例,执行命令
dotnet ef migrations add init
这样就可以生成迁移了,如果要撤销迁移,使用如下命令
dotnet ef migrations remove
如果在无法连接数据库的环境,则会因为无法连接数据库而导致失败,添加参数--force强制删除,而不会去验证数据库里的迁移版本
dotnet ef migrations remove --force
如果使用PM管理控制台,则按如下操作:
将迁移项目设置为启动项目
打开PM管理控制台,默认项目选迁移项目,执行命令添加一个迁移:
Add-Migration init
若想要删除迁移,执行命令
Remove-Migration
如果在无法连接数据库的环境,则会因为无法连接数据库而导致失败,添加参数--force强制删除
Remove-Migration -Force
如果有其他问题,欢迎讨论。