项目

连接字符串管理

当您需要构建或使用模块化系统时,连接字符串管理系统显得尤为重要。若您开发的是单数据库单体应用,可直接采用 ABP启动模板 ,该模板已为您完成基础配置。

ABP框架专为 模块化多租户 场景设计,其连接字符串管理系统也针对这些场景提供支持:

  • 允许为每个模块设置独立连接字符串,使各模块可使用独立物理数据库,甚至可配置不同数据库提供商
  • 支持多租户SaaS应用中为每个租户配置独立连接字符串和独立数据库

同时支持混合场景配置:

  • 支持将模块分组到不同数据库(例如:所有模块共享单数据库,或将两个模块分配至A库、三个模块分配至B库、一个模块分配至C库,其余模块使用D库)
  • 支持像模块分组一样对租户进行数据库分组
  • 支持为每个租户的每个模块配置独立数据库(虽然过多数据库会增加维护难度,但ABP框架仍提供该能力支持)

所有 预构建应用模块 均设计为兼容这些场景。

配置连接字符串

参考以下配置示例:

"ConnectionStrings": {
  "Default": "Server=localhost;Database=MyMainDb;Trusted_Connection=True;",
  "AbpIdentityServer": "Server=localhost;Database=MyIdsDb;Trusted_Connection=True;",
  "AbpPermissionManagement": "Server=localhost;Database=MyPermissionDb;Trusted_Connection=True;"
}

ABP通过IConfiguration服务获取应用配置。虽然最简方式是在appsettings.json中配置,但不仅限于此文件。您可使用环境变量、用户密钥、Azure密钥库等,详见 配置文档

此配置定义了三组连接字符串:

  • MyMainDb(即Default连接字符串)是应用主连接字符串。未指定模块连接字符串时默认回退至此连接。应用启动模板 默认配置为单连接字符串,所有模块共享同一数据库
  • MyIdsDb(即AbpIdentityServer连接字符串)供 IdentityServer模块 使用
  • MyPermissionDb(即AbpPermissionManagement连接字符串)供 权限管理模块 使用

预构建应用模块均定义了连接字符串名称常量。例如 IdentityServer模块AbpIdentityServerDbProperties类(位于Volo.Abp.IdentityServer命名空间)中定义了ConnectionStringName常量。其他模块类似定义常量,您可查看对应模块获取连接字符串名称。

AbpDbConnectionOptions选项类

AbpDbConnectionOptions是用于设置连接字符串和配置数据库结构的选项类。

设置连接字符串

ABP通过AbpDbConnectionOptions获取连接字符串。按上述方式配置后,该选项会自动填充。但您可通过 选项模式 设置或重写连接字符串。在 模块ConfigureServices方法中配置示例如下:

public override void ConfigureServices(ServiceConfigurationContext context)
{
    Configure<AbpDbConnectionOptions>(options =>
    {
        options.ConnectionStrings.Default = "...";
        options.ConnectionStrings["AbpPermissionManagement"] = "...";
    });
}

配置数据库结构

通过AbpDbConnectionOptions类的Databases属性,可将多个模块的连接字符串分组到单一连接字符串。

观察以下连接字符串配置:

"ConnectionStrings": {
  "Default": "Server=localhost;Database=MyMainDb;Trusted_Connection=True;",
  "AbpIdentity": "Server=localhost;Database=MySecondaryDb;Trusted_Connection=True;",
  "AbpIdentityServer": "Server=localhost;Database=MySecondaryDb;Trusted_Connection=True;",
  "AbpPermissionManagement": "Server=localhost;Database=MySecondaryDb;Trusted_Connection=True;"
}

此例定义了四组连接字符串,但后三组实际指向同一数据库MySecondaryDb。主应用与其他模块使用Default连接字符串对应的MyMainDb数据库。

此处目标是将三个模块(AbpIdentityAbpIdentityServerAbpPermissionManagement)分组到同一数据库,但需手动指定每个模块的连接字符串(因为未指定时会回退到Default)。

为消除重复配置,可通过配置AbpDbConnectionOptions.Databases属性实现连接字符串分组(在 模块类ConfigureServices方法中配置):

Configure<AbpDbConnectionOptions>(options =>
{
    options.Databases.Configure("MySecondaryDb", db =>
    {
        db.MappedConnections.Add("AbpIdentity");
        db.MappedConnections.Add("AbpIdentityServer");
        db.MappedConnections.Add("AbpPermissionManagement");
    });
});

随后可简化appsettings.json配置:

"ConnectionStrings": {
  "Default": "Server=localhost;Database=MyMainDb;Trusted_Connection=True;",
  "MySecondaryDb": "Server=localhost;Database=MySecondaryDb;Trusted_Connection=True;"
}

MySecondaryDb成为映射连接的新连接字符串。

ABP优先查找模块特定连接字符串,其次检查数据库映射配置,最终回退到Default连接字符串。

设置连接字符串名称

模块通常通过ConnectionStringName特性为其DbContext类关联唯一连接字符串名称。示例:

[ConnectionStringName("AbpIdentityServer")]
public class IdentityServerDbContext
    : AbpDbContext<IdentityServerDbContext>, IIdentityServerDbContext
{
}

对于 Entity Framework CoreMongoDB ,请在您的 DbContext 类(及对应接口)中标注此特性。通过这种方式,ABP 会为相关DbContext实例使用指定连接字符串。

Entity Framework Core数据库迁移

使用关系数据库需提前创建数据库及数据库结构(表、视图等)。

采用EF Core的启动模板包含单数据库和.EntityFrameworkCore项目,该项目包含相关类及迁移文件。该项目主要定义了YourProjectNameDbContext类,其中调用所用模块的Configure...()方法,如builder.ConfigurePermissionManagement()

当需要分离模块数据库时,通常需要创建第二条迁移路径。请参阅 EF Core 迁移文档 了解如何为指定模块创建并使用独立数据库。

多租户支持

关于为租户配置独立数据库的详细说明,请参阅 多租户文档

替换连接字符串解析器

ABP定义了IConnectionStringResolver接口,并在需要连接字符串时使用该服务。提供两种内置实现:

  • DefaultConnectionStringResolver使用AbpDbConnectionOptions,根据前述"配置连接字符串"章节规则选择连接字符串
  • MultiTenantConnectionStringResolver用于多租户应用,会优先获取当前租户的配置连接字符串。该实现通过ITenantStore查找连接字符串,继承自DefaultConnectionStringResolver,当未指定租户连接字符串时回退到基类逻辑

如需自定义连接字符串确定逻辑,请实现IConnectionStringResolver接口(可从现有实现派生),并通过 依赖注入系统 替换现有实现。

在本文档中