当我们在编写基于数据库的应用程序时,随着需求的增加和改变,我们需要升级我们的数据库,变更数据库表的字段,当我们的系统的不同版本被部署到了不同的客户那里,在需要给客户升级时,我们如何实现数据库模式 (schema) 的自动升级呢?
传统的管理办法是针对每个数据库版本,开发者手工编写升级脚本。在需要升级的时候,找到对应的脚本挨个升级到指定的版本。编写升级脚本是一件枯燥乏味且容易出错的工作,手动升级也需要细心的操作。
数据库迁移工具能否帮助我们解决这个问题,在 JAVA 世界有 Red Gate,Liquibase 这样的解决方案。.Net Core 提供了 Entity Framework 数据迁移工具。它可以帮助我们自动管理数据库模式,把不同版本的数据库升级到最新版本上。
下面以 asp.net core 服务为例,简要介绍如何使用 .Net Core Entity Framework Database Migration Tools
安装 EF 工具
首先我们需要安装 dotnet-ef,打开命令行,输入如下命令:
dotnet tool install --global dotnet-ef
如果不安装这个工具,我们可能会看到下面的错误:
创建数据库项目,建立第一个迁移
进入 Visual Studio 创建一个 asp.net core 项目,然后在 program.cs 里加入以下代码:
builder.Services.AddDbContext<YourDbContext>(
options => options.UseSqlServer("name=ConnectionStrings:DefaultConnection"));
我们的配置文件,应该是这个样子的:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"DefaultConnection": "Server=172.28.64.136;Database=YourDatabaseName;UID=sa;PWD=YourPassword;trustServerCertificate=true"
}
}
新建一个 YourDbContext 类,它应该类似于下面的代码:
public class YourDbContext : DbContext
{
public YourDbContext (DbContextOptions<EnrollmentContext> options) : base(options)
{
}
public DbSet<Enrollment> Enrollments { get; set; }
}
下表是我们的第一个数据库表对应的类,为了不绑定固定的数据库,我们使用了通用的标记:
public class Enrollment
{
public Guid Id { get; set; }
#region OTP
[MaxLength(16)]
public String? OtpPassword { get; set; }
public DateTime? Expiration { get; set; }
#endregion
#region Player Info
[MaxLength(64)]
public string PlayerId { get; set; }
[MaxLength(128)]
public string Name { get; set; }
public DateTime Birthday { get; set; }
[StringLength(3)]
public string CountryIsoCode { get; set; }
[MaxLength(128)]
public string Email { get; set; }
#endregion
}
编译成功后,在项目文件夹下输入下面的命令:
dotnet ef migrations add InitialCreate
命令运行成功后,我们会在项目下发现一个新的文件夹,类似于下面的图片:
执行迁移升级数据库
当我们的第一个迁移建立好了以后,我们就可以连接数据库创建数据库表了。执行下面的命令升级数据库:
dotnet ef database update
升级成功后就可以看到类似于下面的结果了:
修改数据库模式,再次升级数据库
我们发现上面的 Enrollment 表没有记录创建时间。我们给它增加一个字段,名字叫 CreatedDate。现在代码被改为如下:
public class Enrollment
{
public Guid Id { get; set; }
#region OTP
[MaxLength(16)]
public String? OtpPassword { get; set; }
public DateTime? Expiration { get; set; }
#endregion
#region Player Info
[MaxLength(64)]
public string PlayerId { get; set; }
[MaxLength(128)]
public string Name { get; set; }
public DateTime Birthday { get; set; }
[StringLength(3)]
public string CountryIsoCode { get; set; }
[MaxLength(128)]
public string Email { get; set; }
#endregion
public DateTime CreatedDate { get; set; }
}
然后运行下面的命令,增加第二个迁移。注意,在修改完上面的代码以后一定要编译我们的项目,否则下面的命令可能侦测不到代码的变化。
dotnet ef migrations add addEnrollmentCreatedDate
完成以后,项目的 migration 文件夹会增加一个 addEnrollmentCreatedDate.cs 文件。
再次运行下面的命令,我们就可以把代码的变化应用到数据库了:
dotnet ef database update
常见问题
在生产环境如何迁移
上面的方法需要安装 .Net Core SDK, 在生产环境下可以运行以下命令生成执行迁移:
dotnet ef migrations script --idempotent
启动项目和数据库项目分开的问题
如果我们的启动项目 (startup project)和我们的数据库项目是分开建立,那么运行上面的命令可能会出现错误,解决方案是在数据库项目下运行迁移命令,但是需要加上 --startup 参数。类似于下面的示例:
dotnet ef --startup-project ..\EnrollmentApi\ migrations add InitialCreate
SSL Error
如果出现下面的错误,我们需要给数据库连接串加上 trustServerCertificate=true
A connection was successfully established with the server, but then an error occurred during the login process. (provider: SSL Provider, error: 0 - The certificate chain was issued by an authority that is not trusted.)
https://stackoverflow.com/questions/72190575/asp-net-core-web-api-update-database-failed-due-to-provider-ssl-provider-err文章来源:https://www.toymoban.com/news/detail-452496.html
结论
我们可以使用 .Net EF Migrations Tools 来管理我们的数据库变更,这样就可以不用担心客户的数据库版本跟最新版本不一致而导致的变更跟踪太复杂的问题了。文章来源地址https://www.toymoban.com/news/detail-452496.html
到了这里,关于如何使用 .Net Core 实现数据库迁移 (Database Migration)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!