Alva

Alva

programmer
github
telegram
email

Abp 框架统一设置表名前缀和 Schema

太长不看版:

对于内置表,在所有启动项目(不包括 XXX.DbMigrator)的 Program.cs 文件和 XXXDbContextFactory 中,设置 AbpCommonDbPropertiesAbpOpenIddictDbProperties 的值。

如果是我们自己的实体表,那么找到 XXX.Domain/XXXConsts.cs 文件,修改相关值即可。

Abp 框架本身包含一些表,例如 AbpAuditLogs、AbpAuditLogActions 表等,其中 Abp 就是表名前缀,这个值支持修改。

修改 Abp 内置表的表名前缀和 Schema#

生成模板项目#

我们先使用 Cli 来生成模板项目

// abp version 6.0.2
abp new MyApp

打开生成的项目,找到 MyApp.EntityFrameworkCore 项目。

打开 Migrations/MyAppDbContextModelSnapshot.cs 文件,大概在 144 行,可以看到一句

b.ToTable("AbpAuditLogs", (string)null);

可以看到,默认生成的模板项目中,使用 Abp 作为表前缀,而 schema 则设置为 null。

我们将这个 Migrations 文件夹删除。

找到设置表名前缀的地方#

还是 MyApp.EntityFrameworkCore 项目,我们找到 EntityFrameworkCore/MyAppDbContext.cs 文件。

public class MyAppDbContext :
    AbpDbContext<MyAppDbContext>,
    IIdentityDbContext,
    ITenantManagementDbContext
{
    // ...

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        // 这里设置了一些内置表的配置
        builder.ConfigurePermissionManagement();
        builder.ConfigureSettingManagement();
        builder.ConfigureBackgroundJobs();
        builder.ConfigureAuditLogging();
        builder.ConfigureIdentity();
        builder.ConfigureOpenIddict();
        builder.ConfigureFeatureManagement();
        builder.ConfigureTenantManagement();

        // ...
    }
}

找到 OnModelCreating 方法,我们可以进入这些 builder.ConfigureXXX() 方法,看看源码实现。

按住 Ctrl 键,再鼠标左击,可以反编译,看到 Abp 的对应源码。我们点开 ConfigurePermissionManagement 方法,可以看到以下代码

public static void ConfigurePermissionManagement([NotNull] this ModelBuilder builder)
{
    // ...

    builder.Entity<PermissionGrant>(b =>
    {
        // 这里设置了表名前缀,以及 Schema
        b.ToTable(AbpPermissionManagementDbProperties.DbTablePrefix + "PermissionGrants", AbpPermissionManagementDbProperties.DbSchema);

        // ...
    });

    // ...
}

我们可以看到 PermissionGrant 实体对应的表名配置,和 AbpPermissionManagementDbProperties 挂钩。点开其他 builder.ConfigureXXX() 方法,也能看到类似的配置。
那我们继续再找到 AbpPermissionManagementDbProperties 类,继续探索。

public static class AbpPermissionManagementDbProperties
{
    public static string DbTablePrefix { get; set; } = AbpCommonDbProperties.DbTablePrefix;

    public static string DbSchema { get; set; } = AbpCommonDbProperties.DbSchema;

    public const string ConnectionStringName = "AbpPermissionManagement";
}

可以看到有关 PermissionGrant 实体的所有配置,包括表名前缀 DbTablePrefix、Schema DbSchema 和数据库链接字符串名 ConnectionStringName。也就是说,我们可以在项目启动的时候,单独修改这些值,就能修改相关的配置。

AbpPermissionManagementDbProperties 类中的表名前缀 DbTablePrefix 和 Schema DbSchema 都依赖于 AbpCommonDbProperties 类,我们继续找到这个类的实现。

public static class AbpCommonDbProperties
{
    /// <summary>
    /// This table prefix is shared by most of the ABP modules.
    /// You can change it to set table prefix for all modules using this.
    ///
    /// Default value: "Abp".
    /// </summary>
    public static string DbTablePrefix { get; set; } = "Abp";

    /// <summary>
    /// Default value: null.
    /// </summary>
    public static string DbSchema { get; set; } = null;
}

可以看到,这个配置项,就和默认模板生成的配置一致,表名前缀以 Abp 开头,Schema 设置为 null。找到了基础设置项,我们就可以修改默认的配置。

修改默认配置#

在所有的启动项目(不包括 XXX.DbMigrator)中的 Program.cs 文件中,以及 XXXDbContextFactory.cs 文件中,设置配置。

// 所有的启动项目(不包括 `XXX.DbMigrator`)
public class Program
{
    public async static Task<int> Main(string[] args)
    {
        AbpCommonDbProperties.DbSchema      = "abp";
        AbpCommonDbProperties.DbTablePrefix = "ABP_";

        // ...
    }
}

// XXXDbContextFactory.cs (默认生成在 XXX.EntityFrameworkCore/EntityFrameworkCore)
public XXXDbContext CreateDbContext(string[] args)
{
    AbpCommonDbProperties.DbSchema      = "abp";
    AbpCommonDbProperties.DbTablePrefix = "ABP_";

    // ...
}

生成首次迁移代码#

我们需要先删除 XXX.EntityFrameworkCore 项目下的 Migrations 文件夹,这里面是原先默认生成的迁移文件。
然后再运行 XXX.DbMigrator 项目,生成迁移文件。

这次我们再打开 Migrations/MyAppDbContextModelSnapshot.cs 文件,找到 144 行,可以看到生成的迁移代码中已经应用了我们的配置。

// 表名前缀 ABP_
// Schema abp
b.ToTable("ABP_AuditLogs", "abp");

特殊的表#

运行迁移后,我们来到数据库查看,会发现有四张表的表名前缀和 Schema,并没有按我们的预期设置,这几张表以 OpenIddict 为前缀。

我们回到代码中,找到 MyAppDbContext.cs 文件的 OnModelCreating 方法,可以找到这行代码。

builder.ConfigureOpenIddict();

我们重新朔源,反编译查看源码可以看到,以 OpenIddict 为前缀的几个实体类,表配置和 AbpOpenIddictDbProperties 类挂钩,而 AbpOpenIddictDbProperties 类里的配置并没有依赖于 AbpCommonDbProperties,所以我们需要单独设置这几个实体。

// 在前面的 Program.cs 和 XXXDbContextFactory.cs 中,添加以下配置
AbpOpenIddictDbProperties.DbSchema      = "abp";
AbpOpenIddictDbProperties.DbTablePrefix = "ABP_";

重新删除 Migrations 文件夹,清空数据库,然后运行 XXX.DbMigrator 项目,应用迁移后,就可以在数据库看到生成的表了。

单独配置#

MyAppDbContext.cs 文件的 OnModelCreating 方法中的以下代码中,我们可以找到一些相应配置,可以反编译源码,找到每个配置所依赖的 XXXDbProperties,在 Program.csXXXDbContextFactory.cs 文件中,添加相应配置的设置即可。

builder.ConfigurePermissionManagement();
builder.ConfigureSettingManagement();
builder.ConfigureBackgroundJobs();
builder.ConfigureAuditLogging();
builder.ConfigureIdentity();
builder.ConfigureOpenIddict();
builder.ConfigureFeatureManagement();
builder.ConfigureTenantManagement();

用户表的表名前缀和 Schema#

用户表的这些配置比较简单,直接就在生成的代码中可以找到。

// MyApp.Domain 项目
// MyAppConsts 类
public static class MyAppConsts
{
    public const string DbTablePrefix = "App";

    public const string DbSchema = null;
}

修改这些配置就可以了。

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。