在软件开发过程中,数据库的版本控制和迁移是一个复杂且易出错的任务。传统的方法是手动编写SQL脚本来创建和更新数据库表、存储过程、函数等,然后按照一定的顺序执行它们,以确保在不同的开发和部署环境中能够无缝执行。然而,随着项目的发展,手动管理这些数据库变更变得越来越困难。幸运的是,Fluent Migrator的出现解决了这些问题。
Fluent Migrator是一个.NET平台的数据库迁移框架,它使用流畅的接口来操作数据库。使用Fluent Migrator时,通过编写包含两个方法Up()
和Down()
的类来描述数据库的变更。顾名思义,Up()
方法用于升级数据库,而Down()
方法用于降级数据库。这些类可以提交到版本控制系统中。
迁移类是简单的C#类,它们继承自“Migration”基类。每个类都需要在Migration属性中放置一个唯一的标识符,该标识符作为迁移的版本号。这个标识符可以是递增的整数,或者使用YYYYMMDDHHMM的格式,这样当多个开发人员创建迁移时,就不会发生冲突。
然后,实现Up()
和Down()
方法。例如,在Up()
方法中,可以创建一个新表,在Down()
方法中,删除该表。所有的迁移类都保存在一个单独的程序集中。
Fluent Migrator提供了一个迁移运行器工具(Migrate.exe),它按照正确的顺序执行迁移类的Up()
或Down()
方法。可以将这个工具集成到任何CI(持续集成)工具中,如Jenkins、TeamCity或TFS,以自动化迁移过程。
Fluent Migrator还在数据库中维护一个“Version”表,以跟踪哪些迁移版本已经执行。
实现Fluent Migrator是一个简单的任务。首先,在Visual Studio中打开现有应用程序,并在解决方案中添加一个新的“类库”类型的项目。可以将其命名为“DatabaseMigration”。
使用以下命令在“DatabaseMigration”项目中安装Fluent Migrator的NuGet包:
Install-Package FluentMigrator
这将安装最新的包,并将Fluent Migrator的引用添加到项目中。
有关使用NuGet包的更多信息,可以访问以下链接:
现在,在“DatabaseMigration”项目中创建一个新文件夹,并将其命名为“Migrations”以保存所有迁移类。
接下来,在该文件夹中创建一个新类,并将其命名为“M0001_CreateMemberTable.cs”,并粘贴以下代码:
using FluentMigrator;
namespace DatabaseMigration.Migrations
{
[Migration(1)]
public class M0001_CreateMemberTable : Migration
{
public override void Up()
{
Create.Table("Member")
.WithColumn("MemberId").AsInt32().PrimaryKey().Identity()
.WithColumn("Name").AsString(50)
.WithColumn("Address").AsString()
.WithColumn("MobileNo").AsString(10);
}
public override void Down()
{
Delete.Table("Member");
}
}
}
在这里,创建了一个从“Migration”类派生的类,版本号为1,并实现了Up()
和Down()
方法。在Up()
和Down()
方法中,可以运行任何SQL命令,但Fluent Migrator提供了另一种定义模式的方法,即使用Fluent API命令,如Create
、Delete
、Rename
、Insert
、Update
、Execute
等。
在Up()
方法中,创建了一个名为“Member”的表,并添加了一些列。在Down()
方法中,删除了“Member”表。
现在编译项目,然后准备执行迁移。要执行迁移,有“Migrate.exe”,可以在包文件夹的路径“packages\FluentMigrator.1.6.0\tools”中找到。
从命令提示符运行以下命令以执行迁移:
Migrate.exe /connection "data source=localhost;initial catalog=MyTemp;User ID=sa;Password=******;"
/db SQLserver2008 /timeout 600 /target ..\DatabaseMigration\bin\Debug\DatabaseMigration.dll
在这里,传递了数据库的连接字符串,数据库服务器的类型,即SQLserver2008,连接超时以及包含所有迁移类的程序集的路径。
为了简化,在“Utils”文件夹下创建了一个名为“MigrateDatabase.bat”的批处理文件,并将上述命令放入此文件中。当执行此批处理文件时,它将显示以下输出:
上述输出显示,因为第一次执行迁移,所以创建了“Version”表,然后“M0001_CreateMemberTable”迁移成功执行。可以检查数据库,会发现像下面这样创建了两个表:
检查“Version”表。会发现有一条记录,迁移号作为“Version”,日期时间为“AppliedOn”,迁移名称在“Description”列中。
现在让来看另一个非常重要的场景,想要使用迁移类执行SQL脚本。为此,在项目中创建一个单独的文件夹,将其命名为“Scripts”并将SQL脚本放在那里。
例如:放置了两个SQL脚本,一个用于创建存储过程,另一个用于删除该存储过程。 注意:不要忘记将这两个文件的“Build Action”属性设置为“Embedded Resource”。
然后,创建另一个迁移类,将其命名为“M0002_CreateSP_GetAllMember.cs”,并将以下代码粘贴到该类文件中:
using FluentMigrator;
namespace DatabaseMigration.Migrations
{
[Migration(2)]
public class M0002_CreateSP_GetAllMember : Migration
{
public override void Up()
{
Execute.EmbeddedScript("CreateSP_GetAllMember.sql");
}
public override void Down()
{
Execute.EmbeddedScript("DropSP_GetAllMember.sql");
}
}
}
在上述代码中,简单地使用Execute.EmbeddedScript
函数执行SQL脚本。
现在再次运行批处理文件“MigrateDatabase.bat”,会发现存储过程已创建,并且“Version”表现在有两条记录。
要将数据库回滚到特定版本非常简单。需要执行以下命令,并提供版本号。
Migrate.exe /connection "data source=localhost;initial catalog=MyTemp;User ID=sa;Password=******;"
/db SQLserver2008 /timeout 600 /task rollback --steps=1 /target ..\DatabaseMigration\bin\Debug\DatabaseMigration.dll
在这里,使用开关/task rollback
与选项--steps
,并提供版本号=1。因此,它将通过执行版本大于1的所有迁移脚本的Down()
方法,将数据库回滚到版本1。在例子中,它将执行“M0002_CreateSP_GetAllMember.cs”的Down()
方法。
再次,在“Utils”文件夹下创建了一个名为“MigrateDatabase-RollbackToVersion-1.bat”的批处理文件,用于执行上述命令。这将显示以下输出:
输出显示“M0002_CreateSP_GetAllMember”迁移已成功回滚。
现在检查“Version”表,会发现版本号为2的第二条记录已被删除。
通过这种方式,可以轻松地使用Fluent Migrator升级和降级数据库。还可以通过将其与任何CI(持续集成)工具集成,轻松自动化数据库迁移过程。也提供了这个应用程序的源代码以供参考,但要运行它,首先需要安装Fluent Migrator的NuGet包。