分层解决方案:数据库配置
ABP Studio的分层解决方案模板包含了预配置的数据库设置。本文档解释了如何在您的解决方案中管理数据库配置。
连接字符串
连接字符串存储在 appsettings.json 文件中。您可以通过修改相应的 appsettings.json 文件来为不同的环境自定义它们。默认情况下,*.DbMigrator 项目和一个Web应用程序项目使用 Default 连接字符串。
要更改 Default 键的连接字符串,请更新项目中的 appsettings.json 文件。连接字符串在 ConnectionStrings 部分下定义,如下所示:
{
"ConnectionStrings": {
"Default": "Server=(LocalDb)\\MSSQLLocalDB;Database=Bookstore;Trusted_Connection=True;TrustServerCertificate=true"
}
}
DbContext 类
在 *.EntityFrameworkCore 项目中,定义了 DbContext 类。该 DbContext 类派生自 AbpDbContext 类,后者是 ABP 框架的一部分。
[ReplaceDbContext(typeof(IIdentityProDbContext))]
[ReplaceDbContext(typeof(ISaasDbContext))]
[ConnectionStringName("Default")]
public class BookstoreDbContext :
AbpDbContext<BookstoreDbContext>,
ISaasDbContext,
IIdentityProDbContext
{
#region 来自模块的实体
// 身份认证
public DbSet<IdentityUser> Users { get; set; }
public DbSet<IdentityRole> Roles { get; set; }
public DbSet<IdentityClaimType> ClaimTypes { get; set; }
public DbSet<OrganizationUnit> OrganizationUnits { get; set; }
public DbSet<IdentitySecurityLog> SecurityLogs { get; set; }
public DbSet<IdentityLinkUser> LinkUsers { get; set; }
public DbSet<IdentityUserDelegation> UserDelegations { get; set; }
public DbSet<IdentitySession> Sessions { get; set; }
// SaaS(软件即服务)
public DbSet<Tenant> Tenants { get; set; }
public DbSet<Edition> Editions { get; set; }
public DbSet<TenantConnectionString> TenantConnectionStrings { get; set; }
#endregion
public BookstoreDbContext(DbContextOptions<BookstoreDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.ConfigurePermissionManagement();
builder.ConfigureSettingManagement();
builder.ConfigureBackgroundJobs();
builder.ConfigureAuditLogging();
builder.ConfigureFeatureManagement();
builder.ConfigureIdentityPro();
builder.ConfigureOpenIddictPro();
builder.ConfigureLanguageManagement();
builder.ConfigureSaas();
builder.ConfigureTextTemplateManagement();
builder.ConfigureGdpr();
builder.ConfigureCmsKit();
builder.ConfigureCmsKitPro();
builder.ConfigureBlobStoring();
/* 在此处配置您自己的表/实体 */
//builder.Entity<YourEntity>(b =>
//{
// b.ToTable(BookstoreConsts.DbTablePrefix + "YourEntities", BookstoreConsts.DbSchema);
// b.ConfigureByConvention(); // 自动配置基类属性
// //...
//});
}
}
ConnectionStringName 特性
我们在 BookstoreDbContext 类中使用的是 Default 连接字符串。您可以通过更新 ConnectionStringName 特性来更改连接字符串的名称。
[ConnectionStringName("Default")]
ConnectionStringName 特性定义了该 DbContext 类正在使用的连接字符串的唯一名称。它与 appsettings.json 文件中定义的连接字符串相匹配。该名称还在数据库迁移中用于区分不同的数据库模式,并在为多租户系统存储租户连接字符串时用作键。
ReplaceDbContext 特性
[ReplaceDbContext(typeof(IIdentityProDbContext))]
[ReplaceDbContext(typeof(ISaasDbContext))]
应用程序的 DbContext 利用了 身份认证 和 SaaS * 模块,并创建了一个包含这些模块数据库模式的单一数据库。这些模块通常定义自己的 DbContext 类。但是 ReplaceDbContext 特性 告诉 ABP 使用这个 (BookstoreDbContext) DbContext 类,而不是这些模块定义的 DbContext 类。从技术上讲,它会在运行时替换给定的 DbContext 类。我们这样做是为了确保在使用这些多个模块时,我们拥有一个单一的(合并的)数据库模式、单一的数据库迁移路径和单一的事务操作。当我们替换一个 DbContext 时,我们应该实现它的接口,就像 BookstoreDbContext 类所做的那样:
public class BookstoreDbContext :
AbpDbContext<BookstoreDbContext>,
ISaasDbContext,
IIdentityProDbContext
- 该类实现了
ISaasDbContext和IIdentityProDbContext,因此这些模块可以使用它。
接下来,BookstoreDbContext 类定义了以下由所实现接口强制的属性:
// 身份认证
public DbSet<IdentityUser> Users { get; set; }
public DbSet<IdentityRole> Roles { get; set; }
public DbSet<IdentityClaimType> ClaimTypes { get; set; }
public DbSet<OrganizationUnit> OrganizationUnits { get; set; }
public DbSet<IdentitySecurityLog> SecurityLogs { get; set; }
public DbSet<IdentityLinkUser> LinkUsers { get; set; }
public DbSet<IdentityUserDelegation> UserDelegations { get; set; }
public DbSet<IdentitySession> Sessions { get; set; }
// SaaS
public DbSet<Tenant> Tenants { get; set; }
public DbSet<Edition> Editions { get; set; }
public DbSet<TenantConnectionString> TenantConnectionStrings { get; set; }
OnModelCreating 方法
OnModelCreating 方法用于配置数据库模式。它调用 ABP 框架的 Configure* 方法来为模块配置数据库模式。您也可以在此方法中配置自己的表/实体。
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.ConfigurePermissionManagement();
builder.ConfigureSettingManagement();
builder.ConfigureBackgroundJobs();
builder.ConfigureAuditLogging();
builder.ConfigureFeatureManagement();
builder.ConfigureIdentityPro();
builder.ConfigureOpenIddictPro();
builder.ConfigureLanguageManagement();
builder.ConfigureSaas();
builder.ConfigureTextTemplateManagement();
builder.ConfigureGdpr();
builder.ConfigureCmsKit();
builder.ConfigureCmsKitPro();
builder.ConfigureBlobStoring();
/* 在此处配置您自己的表/实体 */
//builder.Entity<YourEntity>(b =>
//{
// b.ToTable(BookstoreConsts.DbTablePrefix + "YourEntities", BookstoreConsts.DbSchema);
// b.ConfigureByConvention(); // 自动配置基类属性
// //...
//});
}
Configure*方法是在每个模块的EntityFrameworkCore项目中定义的扩展方法。这些方法用于为其各自的模块配置数据库模式。在运行时,DbContext类仅针对使用ReplaceDbContext特性的DbContext类被BookstoreDbContext类替换。对于其他模块,它们使用自己专用的DbContext类而不进行替换。
IDesignTimeDbContextFactory 的实现
IDesignTimeDbContextFactory 接口用于在设计时创建 DbContext 实例。EF Core 工具使用它来创建迁移和更新数据库。BookstoreDbContextFactory 类实现了 IDesignTimeDbContextFactory 接口,以创建 BookstoreMigrationsDbContext 实例。
public class BookstoreDbContextFactory : IDesignTimeDbContextFactory<BookstoreDbContext>
{
public BookstoreDbContext CreateDbContext(string[] args)
{
var configuration = BuildConfiguration();
BookstoreEfCoreEntityExtensionMappings.Configure();
var builder = new DbContextOptionsBuilder<BookstoreDbContext>()
.UseSqlServer(configuration.GetConnectionString("Default"));
return new BookstoreDbContext(builder.Options);
}
private static IConfigurationRoot BuildConfiguration()
{
var builder = new ConfigurationBuilder()
.SetBasePath(Path.Combine(Directory.GetCurrentDirectory(), "../Acme.Bookstore.DbMigrator/"))
.AddJsonFile("appsettings.json", optional: false);
return builder.Build();
}
}
配置
在 *.EntityFrameworkCore 项目中,BookstoreEntityFrameworkCoreModule 类用于配置数据库上下文。
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAbpDbContext<BookstoreDbContext>(options =>
{
/* 移除 "includeAllEntities: true" 以仅为聚合根创建
* 默认存储库 */
options.AddDefaultRepositories(includeAllEntities: true);
});
Configure<AbpDbContextOptions>(options =>
{
/* 更改 DBMS 的主要位置。
* 另请参阅用于 EF Core 工具的 BookstoreDbContextFactory。 */
options.UseSqlServer();
});
}
我们主要是将 SQL Server 设置为该应用程序的默认 DBMS,并将 BookstoreDbContext 类注册到依赖注入系统中。
SaaS 模块:租户管理 UI *
SaaS 模块提供了必要的 UI 来设置和更改租户的连接字符串,并触发数据库迁移。
连接字符串管理模态框
您可以在 SaaS 模块的 租户 页面中,为某个租户点击 操作 下拉按钮中的 数据库连接字符串 命令:
它会打开 数据库连接字符串 模态框,如下图所示:
在这里,我们可以为该租户设置一个 默认连接字符串。
当您进行更改并保存对话框后,数据库会自动创建和迁移。如果您稍后更新连接字符串(例如更改数据库名称),它也会再次触发数据库迁移过程。
手动应用数据库迁移
如果您需要为特定租户手动触发数据库迁移,请在 SaaS 模块的 租户管理 页面上,点击相关租户的 操作 下拉菜单,并选择 应用数据库迁移 命令:
抠丁客





