1. <output id="hzk7v"><pre id="hzk7v"><address id="hzk7v"></address></pre></output>
      <output id="hzk7v"></output>
    2. <nav id="hzk7v"><i id="hzk7v"><em id="hzk7v"></em></i></nav>
    3. <listing id="hzk7v"><delect id="hzk7v"><em id="hzk7v"></em></delect></listing>

      如何利用FluentMigrator实现数据库迁移

       更新时间£º2019年04月04日 11:26:31   作者£ºLamond Lu   我要评论

      这篇文章主要给大家介绍了关于如何利用FluentMigrator实现数据库迁移的相关资料£¬文中通过示例代码介绍的非常详细£¬对大家的学习或者工作具有一定的参考学习价值£¬需要的朋友们下面来一起学习学习吧

      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¡£

      支持的数据库列表

      • 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个不同的类库来支持不同的场景¡£

      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的命令行程序¡£

      # 迁移脚本基础库
      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");
        }
       }
      }

      运行迁移类

      编写完迁移类之后£¬我们就可以开始运行迁移类了¡£

      Fluent Migrator有两种运行迁移脚本的方式¡£

      • 使用进程内执行器£¨推荐£©
      • 使用进程外执行器

      使用进程内执行器

      所谓的进?#24515;?#25191;行器£¬其实就是借助FluentMigrator.Runner库£¬在程序内部手动调用IMigrationRunner接口对象的MigrateUp方法执行数据库迁移¡£

      这里我们可以修改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();
        }
       }

      启动程序之后£¬迁移自动完成¡£

       

      使用进程外执行器

      如果你想使用进?#22411;?#36801;移执行器£¬这里首先需要保证你已经安装了.NET Core 2.1或以?#20064;?#26412;的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的抽象类£¬并实现两个抽象方法Up和Down, 顾名?#23478;å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格式来标记迁移类£©£¬这个编号必须是唯一的£¬不能重?#30784;?/p>

      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的特性£¬使用?#38376;?#32622;£¬开发人员可以对针对的不同的环?#24120;?#24320;发环?#24120;?#27979;试环?#24120;?#29983;产环境等£©运行不同的脚本¡£

      [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做数据库迁移的时候£¬?#19981;?#22312;数据库中创建一个VersionInfo表£¬并在其中保存运行过的脚本Id

      区别:

      • EF/EF Core的迁移脚本是根据EF上下文配置以及最新的ModelSnapshot自动生成的£¬更方便一些¡£Fluent Migrator的迁移脚本£¬都需要自己手动编写, 更灵活一些¡£
      • EF/EF Core?#30475;?#33258;动生成的迁移文件一个cs文件一个Design.cs文件£¬每个cs文件中包含了自动生成的脚本类£¬Design.cs里面包含了针对当前迁移类的最新ModelSnapshot, 所以重度使用EF/EF Core, 最后累计生成的Design.cs文件都会非常大¡£Fluent Migrator的每个迁移类都是自己编写的£¬只包含本次迁移的内容£¬所以体积更小¡£

      总结

      本篇中我描述了Fluent Migrator的一些基本用法£¬以及它与EF/EF Core脚本迁移的区别£¬ 如果你不是重度EF/EF Core的使用者£¬可以尝试一下使用Fluent Migrator来做数据库迁移¡£

      好了£¬以上就是这篇文章的全部内容了£¬希望本文的内容对大家的学习或者工作具有一定的参考学习价值£¬谢谢大家对脚本之家的支持¡£

    4. 最锋利的Visual Studio Web开发工具扩展£ºWeb Essentials使用详解

      最锋利的Visual Studio Web开发工具扩展£ºWeb Essentials使用详解

      Web Essentials是目前为止见过的最好用的VS扩展工具了£¬具体功能请待我一一道来¡£
      2016-06-06
    5. ASP.NET使用GridView导出Excel实现方法

      ASP.NET使用GridView导出Excel实现方法

      这篇文章主要介绍了ASP.NET使用GridView导出Excel实现方法,是asp.net操作office文件的一个典型应用,代码中备有较为详尽的注释便于读者理解,需要的朋友可以参考下
      2014-11-11
    6. aspxgridview CustomButtonCallback 不支?#20540;?#20986;消息提示解决方法

      aspxgridview CustomButtonCallback 不支?#20540;?#20986;消息提示解决方法

      aspxgridveiw是devexpress的一个grid控件£¬使用起来还不错£¬不能再 CustomButtonCallback 事件中使用response.write£¬具体的解决方法如下£¬?#34892;?#36259;的朋友可以参考下哈
      2013-06-06
    7. 详解ASP.NET页面生命周期

      详解ASP.NET页面生命周期

      这篇文章主要为大家介绍了ASP.NET页面生命周期£¬熟悉页面生命周期非常重要£¬这样我们才能在生命周期的合?#24335;?#27573;编写代码,需要的朋友可以参考下
      2015-12-12
    8. Asp.net实现直接在浏览器预览Word¡¢Excel¡¢PDF¡¢Txt文件£¨附源码£©

      Asp.net实现直接在浏览器预览Word¡¢Excel¡¢PDF¡¢Txt文件£¨附源码

      本文主要介绍了Asp.net实现直接在浏览器预览Word¡¢Excel¡¢PDF¡¢Txt文件的具体实例¡£文章篇尾附上源码下载£¬有兴趣的朋友可以看下
      2016-12-12
    9. 区分ASP.NET中get方法和post方法

      区分ASP.NET中get方法和post方法

      我们都知道£¬get是从服务器上获取数据£¬post是向服务器上传数据¡£本文主要介绍ASP.NET中get方法和post方法的区别£¬需要的朋友可以参考下
      2015-10-10
    10. .NET中的 类型转换深入理解

      .NET中的 类型转换深入理解

      CLR最重要的一个特性就是类型安全,CLR在运行时总能知道一个对象的类型,我们也可以通过调用GetType()方法£¬来得到对象的准确类型,接下来详细介绍£¬?#34892;?#36259;的朋友可以了解下
      2013-01-01
    11. 最新评论

      常用在线小工具

      3dÊÔ»úºÅÖвÊÍø

        1. <output id="hzk7v"><pre id="hzk7v"><address id="hzk7v"></address></pre></output>
          <output id="hzk7v"></output>
        2. <nav id="hzk7v"><i id="hzk7v"><em id="hzk7v"></em></i></nav>
        3. <listing id="hzk7v"><delect id="hzk7v"><em id="hzk7v"></em></delect></listing>

            1. <output id="hzk7v"><pre id="hzk7v"><address id="hzk7v"></address></pre></output>
              <output id="hzk7v"></output>
            2. <nav id="hzk7v"><i id="hzk7v"><em id="hzk7v"></em></i></nav>
            3. <listing id="hzk7v"><delect id="hzk7v"><em id="hzk7v"></em></delect></listing>