GPT4.0+Midjourney绘画+国内大模型 会员永久免费使用!
【 如果你想靠AI翻身,你先需要一个靠谱的工具! 】
FluentMigrator
Fluent Migrator是一个基于.NET的迁移框架,你可以像使用Ruby on Rails Migrations一样使用它。Fluent Migrator的最新版本是3.13版,官网地址https://github.com/fluentmigrator/fluentmigrator。 你可以使用C#编写数据库迁移类,而不需要编写任何SQL脚本。从使用方式上看,它非常像EF/EF Core的数据库迁移脚本,但是它支持的数据库类型比EF/EF Core多的多,且不受限与EF/EF Core。
支持的数据库列表
Fluent Migrator提供了5个不同的类库来支持不同的场景。
Package | 描述 |
---|---|
FluentMigrator | 创建数据库所需的基础程序集 |
FluentMigrator.Runner | 进程内执行数据库迁移所需的程序集 |
FluentMigrator.Console | 进程外执行数据库迁移所需的程序集,它兼容.NET 4.0/4.5/.NET Core 2.0 |
FluentMigrator.MSBuild | 兼容.NET 4.0/4.5/.NET Standard 2.0的MSBuild任务 |
FluentMigrator.DotNet.Cli | 可执行数据库迁移的.NET Core CLI工具 |
入门例子
这里我们首先演示一个最简单的数据库迁移例子,为一个MySql数据库添加一个日志表。
创建控制台程序
我们使用.NET Core CLI创建一个.NET Core的命令行程序。
1 2 3 4 5 6 7 8 9 10 11 | # 迁移脚本基础库 dotnet add package FluentMigrator # 迁移脚本运行库 dotnet add package FluentMigrator.Runner # 针对MySQL的迁移脚本支持库 dotnet add package FluentMigrator.Runner.MySQL # ADO.NET针对MySQL的驱动器 dotnet add package MySQL.Data |
添加第一个数据库迁移类
未了创建一个名为Log的表,这里需要创建一个数据库迁移类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | using FluentMigrator; namespace test { [Migration(20180430121800)] public class AddLogTable : Migration { public override void Up() { Create.Table( "Log" ) .WithColumn( "Id" ).AsInt64().PrimaryKey().Identity() .WithColumn( "Text" ).AsString(); } public override void Down() { Delete.Table( "Log" ); } } } |
运行迁移类
编写完迁移类之后,我们就可以开始运行迁移类了。
Fluent Migrator有两种运行迁移脚本的方式。
使用进程内执行器
所谓的进行内执行器,其实就是借助FluentMigrator.Runner库,在程序内部手动调用IMigrationRunner接口对象的MigrateUp方法执行数据库迁移。
这里我们可以修改Program.cs文件如下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | class Program { static void Main( string [] args) { var serviceProvider = CreateServices(); using (var scope = serviceProvider.CreateScope()) { UpdateDatabase(scope.ServiceProvider); } } private static IServiceProvider CreateServices() { return new ServiceCollection() //添加FluentMigrator基础服务 .AddFluentMigratorCore() .ConfigureRunner(rb => rb //添加MySql 5.0支持 .AddMySql5() //配置连接字符串 .WithGlobalConnectionString( "server=localhost;port=3307;Database=abc;UID=root;PWD=123456" ) //检索迁移配置 .ScanIn( typeof (AddLogTable).Assembly).For.Migrations()) //启用控制台日志 .AddLogging(lb => lb.AddFluentMigratorConsole()) //构建服务提供器 .BuildServiceProvider( false ); } private static void UpdateDatabase(IServiceProvider serviceProvider) { //初始化进程内迁移构建器 var runner = serviceProvider.GetRequiredService<IMigrationRunner>(); //执行迁移脚本 runner.MigrateUp(); } } |
启动程序之后,迁移自动完成。
使用进程外执行器
如果你想使用进行外迁移执行器,这里首先需要保证你已经安装了.NET Core 2.1或以上版本的SDK, 因为你需要使用.NET Core 2.1之后新增的Global Tool功能。
这里我们可以使用命令行,添加FluentMigrator.DotNet.Cli这个工具
1 | dotnet tool install -g FluentMigrator.DotNet.Cli |
安装完成之后,我们就可以使用这个工具来做数据库迁移了
1 | dotnet fm migrate -p mysql -c "server=localhost;port=3307;Database=abc;UID=root;PWD=123456" -a ".\bin\Debug\netcoreapp2.1\test.dll" |
这个方法有3个参数, 第一个参数-p指定了数据库的类型,第二个参数-c指定了连接字符串,第三个参数-a指定了包含迁移类的程序集路径。
注意:其实这里还有第四个参数command, 可选值为down/up, 如果不指定,默认是up, 即运行所有还未运行过的数据库迁移类。
方法执行后,效果和进程内执行器的效果一致。
基本概念
在展示了一个简单示例之后,我们接下来看一下Fluent Migrator中的一些基本概念。
迁移(Migrations)
Fluent Migrator中最基础的元素是迁移类,每个迁移类都需要继承自一个名为Migration的抽象类,并实现两个抽象方法Up和Down, 顾名思义Up方法即执行当前的数据库变更,Down方法即回滚当前的数据库变更。
1 2 3 4 5 6 7 8 9 10 11 12 13 | [Migration(1)] public class CreateUserTable : Migration { public override void Up() { Create.Table( "Users" ); } public override void Down() { Delete.Table( "Users" ); } } |
这里你可能注意到迁移类的头部,有一个Migration的特性,它的值是1, 这里其实是指定了迁移类执行的顺序,编号越小的迁移类越先执行(有一部分开发人员系统会使用当前日期的yyyyMMddHHmmss格式来标记迁移类),这个编号必须是唯一的,不能重复。
Fluent接口(Fluent Interface)
Fluent Migrator提供非常丰富的fluent api, 我们可以使用这些api来创建表,列,索引。 基本上你能用到的大部分场景它都支持。
创建表达式(Create Expression)
你可以使用它创建表达式来添加表,列,索引,外键,组织结构(schema)
1 2 3 | Create.Table( "Users" ) .WithIdColumn() .WithColumn( "Name" ).AsString().NotNullable(); |
注:WithIdColumn()是一个扩展方法,它等价于.WithColumn("Id").AsInt32().NotNullable().PrimaryKey().Identity();
1 2 3 | Create.ForeignKey() .FromTable( "Users" ).ForeignColumn( "CompanyId" ) .ToTable( "Company" ).PrimaryColumn( "Id" ); |
变更表达式(Alter Expression)
用来变更已存在的表和列
1 2 3 4 | Alter.Table( "Bar" ) .AddColumn( "SomeDate" ) .AsDateTime() .Nullable(); |
1 2 3 4 | Alter.Table( "Bar" ) .AlterColumn( "SomeDate" ) .AsDateTime() .NotNullable(); |
1 2 3 4 | Alter.Column( "SomeDate" ) .OnTable( "Bar" ) .AsDateTime() .NotNullable(); |
删除表达式(Delete Expression)
用来删除表,列,外键,组织结构(Schema)
1 | Delete.Table( "Users" ); |
删除多个列(Delete Multiple Columns)
Fluent Migrator也提供了一个删除多列的语法
1 | Delete.Column( "AllowSubscription" ).Column( "SubscriptionDate" ).FromTable( "Users" ); |
执行脚本(Execute Expression)
允许你执行自定义的SQL脚本或执行指定的SQL脚本文件
1 2 3 | Execute.Script( "myscript.sql" ); Execute.EmbeddedScript( "UpdateLegacySP.sql" ); Execute.Sql( "DELETE TABLE Users" ); |
这里EmbeddedScript方法也是执行指定的SQL脚本文件,但是它的文件来源Embbed Resource中读取。如果你想使用EmbbedScript只需要将指定的SQL脚本文件的Build Action属性设置为Embbed Resource即可。
重命名表达式(Rename Expression)
允许重命名表或列
1 2 | Rename.Table( "Users" ).To( "UsersNew" ); Rename.Column( "LastName" ).OnTable( "Users" ).To( "Surname" ); |
数据操作表达式(Data Expressions)
允许对数据库数据进行新增/修改/删除操作
1 | Insert.IntoTable( "Users" ).Row( new { FirstName = "John" , LastName = "Smith" }); |
1 2 3 | Delete.FromTable( "Users" ).AllRows(); //删除所有行 Delete.FromTable( "Users" ).Row( new { FirstName = "John" }); //删除所有FirstName = John的数据行 Delete.FromTable( "Users" ).IsNull( "Username" ); //删除所有Username为空的数据行 |
1 | Update.Table( "Users" ).Set( new { Name = "John" }).Where( new { Name = "Johnanna" }); |
数据库类型判断表达式(IfDatabase Expression)
允许根据数据库类型,执行不同的数据库迁移操作
1 2 3 4 5 6 7 8 9 | IfDatabase( "SqlServer" , "Postgres" ) .Create.Table( "Users" ) .WithIdColumn() .WithColumn( "Name" ).AsString().NotNullable(); IfDatabase( "Sqlite" ) .Create.Table( "Users" ) .WithColumn( "Id" ).AsInt16().PrimaryKey() .WithColumn( "Name" ).AsString().NotNullable(); |
组织结构存在表达式(Schema.Exists Expressions)
用来判断组织结构是否已经存在,列如判断表是否存在,列是否存在等等。
1 2 3 4 | if (!Schema.Table( "Users" ).Column( "FirstName" ).Exists()) { this .Create.Column( "FirstName" ).OnTable( "Users" ).AsAnsiString(128).Nullable(); } |
配置(Profile)
Fluent Migrator还提供了一个Profile的特性,使用该配置,开发人员可以对针对的不同的环境(开发环境,测试环境,生产环境等)运行不同的脚本。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | [Profile( "Development" )] public class CreateDevSeedData : Migration { public override void Up() { Insert.IntoTable( "User" ).Row( new { Username = "devuser1" , DisplayName = "Dev User" }); } public override void Down() { //empty, not using } } |
和EF/EF Core的脚本迁移比较
Fluent Migrator的数据库脚本迁移与EF/EF Core非常类似。
相似点:
区别:
总结
本篇中我描述了Fluent Migrator的一些基本用法,以及它与EF/EF Core脚本迁移的区别, 如果你不是重度EF/EF Core的使用者,可以尝试一下使用Fluent Migrator来做数据库迁移。
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。