如何使用FluentMigrator进行数据库迁移

标题:如何使用FluentMigrator进行数据库迁移
地址:http://www.javashuo.com/article/p-oxqkzhdd-km.html
做者: Lamond Luhtml

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。mysql

支持的数据库列表

  • Microsoft SQL Server 2017
  • Microsoft SQL Server 2016
  • Microsoft SQL Server 2014
  • Microsoft SQL Server 2008
  • Microsoft SQL Server 2005
  • Microsoft SQL Server 2000
  • Microsoft SQL Server Compact Edition
  • PostgreSQL
  • MySQL 4
  • MySQL 5
  • Oracle
  • Oracle (managed ADO.NET)
  • Oracle (DotConnect ADO.NET)
  • Microsoft JET Engine (Access)
  • SQLite
  • Firebird
  • Amazon Redshift
  • SAP Hana
  • SAP SQL Anywhere
  • DB2
  • DB2 iSeries

Fluent Migrator提供了5个不一样的类库来支持不一样的场景。git

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数据库添加一个日志表。github

建立控制台程序

咱们使用.NET Core CLI建立一个.NET Core的命令行程序。sql

dotnet new console

添加程序集

接下来,咱们须要添加必要的程序集。shell

# 迁移脚本基础库
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的表,这里须要建立一个数据库迁移类数据库

  • Log表中有2个字段,一个是Id字段,一个是Text字段
  • Id字段是Int64类型的主键,且自增
  • Text字段是字符串字段
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");
        }
    }
}

运行迁移类

编写完迁移类以后,咱们就能够开始运行迁移类了。express

Fluent Migrator有两种运行迁移脚本的方式。c#

  • 使用进程内执行器(推荐)
  • 使用进程外执行器

使用进程内执行器

所谓的进行内执行器,其实就是借助FluentMigrator.Runner库,在程序内部手动调用IMigrationRunner接口对象的MigrateUp方法执行数据库迁移。api

这里咱们能够修改Program.cs文件以下。

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这个工具

dotnet tool install -g FluentMigrator.DotNet.Cli

安装完成以后,咱们就可使用这个工具来作数据库迁移了

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的抽象类,并实现两个抽象方法UpDown, 顾名思义Up方法即执行当前的数据库变动,Down方法即回滚当前的数据库变动。

[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)

Create.Table("Users")
    .WithIdColumn() 
    .WithColumn("Name").AsString().NotNullable();

注:WithIdColumn()是一个扩展方法,它等价于.WithColumn("Id").AsInt32().NotNullable().PrimaryKey().Identity();

Create.ForeignKey() 
    .FromTable("Users").ForeignColumn("CompanyId")
    .ToTable("Company").PrimaryColumn("Id");

变动表达式(Alter Expression)

用来变动已存在的表和列

Alter.Table("Bar")
    .AddColumn("SomeDate")
    .AsDateTime()
    .Nullable();
Alter.Table("Bar")
    .AlterColumn("SomeDate")
    .AsDateTime()
    .NotNullable();
Alter.Column("SomeDate")
    .OnTable("Bar")
    .AsDateTime()
    .NotNullable();

删除表达式(Delete Expression)

用来删除表,列,外键,组织结构(Schema)

Delete.Table("Users");

删除多个列(Delete Multiple Columns)

Fluent Migrator也提供了一个删除多列的语法

Delete.Column("AllowSubscription").Column("SubscriptionDate").FromTable("Users");

执行脚本(Execute Expression)

容许你执行自定义的SQL脚本或执行指定的SQL脚本文件

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)

容许重命名表或列

Rename.Table("Users").To("UsersNew");
Rename.Column("LastName").OnTable("Users").To("Surname");

数据操做表达式(Data Expressions)

容许对数据库数据进行新增/修改/删除操做

Insert.IntoTable("Users").Row(new { FirstName = "John", LastName = "Smith" });
Delete.FromTable("Users").AllRows(); //删除全部行
Delete.FromTable("Users").Row(new { FirstName = "John" }); //删除全部FirstName = John的数据行
Delete.FromTable("Users").IsNull("Username"); //删除全部Username为空的数据行
Update.Table("Users").Set(new { Name = "John" }).Where(new { Name = "Johnanna" });

数据库类型判断表达式(IfDatabase Expression)

容许根据数据库类型,执行不一样的数据库迁移操做

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)

用来判断组织结构是否已经存在,列如判断表是否存在,列是否存在等等。

if (!Schema.Table("Users").Column("FirstName").Exists())
{
    this.Create.Column("FirstName").OnTable("Users").AsAnsiString(128).Nullable();
}

配置(Profile)

Fluent Migrator还提供了一个Profile的特性,使用该配置,开发人员能够对针对的不一样的环境(开发环境,测试环境,生产环境等)运行不一样的脚本。

[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很是相似。

类似点:

  • 当咱们使用EF/EF Core作数据库迁移的时候,会在当前数据库中建立一个__EFMigrationsHistory表,并在其中保存运行过的脚本Id。
  • 当咱们使用Fluent Migrator作数据库迁移的时候,也会在数据库中建立一个VersionInfo表,并在其中保存运行过的脚本Id

区别:

  • EF/EF Core的迁移脚本是根据EF上下文配置以及最新的ModelSnapshot自动生成的,更方便一些。Fluent Migrator的迁移脚本,都须要本身手动编写, 更灵活一些。
  • EF/EF Core每次自动生成的迁移文件一个cs文件一个Design.cs文件,每一个cs文件中包含了自动生成的脚本类,Design.cs里面包含了针对当前迁移类的最新ModelSnapshot, 因此重度使用EF/EF Core, 最后累计生成的Design.cs文件都会很是大。Fluent Migrator的每一个迁移类都是本身编写的,只包含本次迁移的内容,因此体积更小。

总结

本篇中我描述了Fluent Migrator的一些基本用法,以及它与EF/EF Core脚本迁移的区别, 若是你不是重度EF/EF Core的使用者,能够尝试一下使用Fluent Migrator来作数据库迁移。

相关文章
相关标签/搜索