配置数据库表前缀

ABP踩坑记录-目录

本篇其实和ABP关系并不大,主要是EF Core的一些应用-.-。

起因

支持数据库表前缀应该是很多应用中比较常见的功能,而在ABP中并没直接提供这一功能,所以在我们的应用中,我们转而借助EF Core的配置来实现数据库表前缀的配置。

解决方案

这里我结合了Fluent API和数据注解的形式进行配置。

首先,约定所有自定义的表,在其实体类型上都标注了[Table("tablename")]属性。

然后在QincaiDbContext中重载OnModelCreating方法。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
var entityTypes = modelBuilder.Model.GetEntityTypes().ToList();
// 设置自定义表前缀
foreach (var entityType in entityTypes)
{
if (entityType.ClrType
.GetCustomAttributes(typeof(TableAttribute), true)
.FirstOrDefault() is TableAttribute table)
{
// 如果你的表名就是实体类型名的话,可以修改为如下形式,就不必给出[table]的Name参数
// string tableName = tablePrefix + entityType.ClrType.Name;
// 如若有其他需求也可在此进行修改
string tableName = tablePrefix + table.Name;
modelBuilder.Entity(entityType.ClrType)
.ToTable(tableName);
}
}
// 设置内置表前缀
modelBuilder.ChangeAbpTablePrefix<Tenant, Role, User>(tablePrefix);
}

经历

因为采用的Module Zero模板,其数据库上下文中已包含部分内置表,ABP Module Zero也提供了拓展方法ModelBuilder.ChangeAbpTablePrefix<TTenant, TRole, TUser>以便于修改表前缀,其默认的表前缀为Abp

剩下就是配置我们自己定义的表的前缀,这里我们考虑将表前缀以字符串常量的形式储存。

参考资料:EF Core文档

如果你喜欢用Fluent API来配置数据库,那么解决方案就很简单了,直接拼接字符串生成新表名即可。

可以参考以下代码:

// 这里tablePrefix为字符串常量
modelBuilder.Entity<Blog>().ToTable(tablePrefix + "Blogs");

但是,如果每一个类型都需要配置的话,不免显得有些冗长。因此,我便考虑通过反射的方式来统一配置表前缀。

首先,我们需要获取到所有的实体类型。

// 这里需要注意需要将迭代对象作临时存储
// 直接foreach的话会报错,即不能修改迭代中的对象
var entityTypes = modelBuilder.Model.GetEntityTypes().ToList(); foreach (var entityType in entityTypes)
{
// 配置表前缀
// ...
}

然后便是表前缀的配置,一开始我的想法是直接通过实体类型名来配置表名,但在考虑实际情况后,我认为还是需要有一定的灵活度使得该解决方案更通用。

最终,这里我选择用数据注解的方式来为指定表名,即利用[Table]特性。

因为,这是EF Core官方所提供配置方式之一,不会让大家因为配置表前缀而增删过多代码。

我们会用到[Table]特性的Name参数,例如这样:

using System.ComponentModel.DataAnnotations.Schema;

[Table("blogs")]
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}

因为特性并不支持在其参数中引用字符串常量,所以[Table($"{tablePrefix}blogs")]这种写法是不存在的,大家清醒一下。

然后,就是使用Fluent API来配置表前缀了。

// 通过反射获取该实体类上定义的TableAttribute
// 这里没有处理table为null的情况
TableAttribute table = (TableAttribute)entityType.ClrType
.GetCustomAttributes(typeof(TableAttribute), true)
.FirstOrDefault(); // 利用TableAttribute中的Name参数来配置表名
modelBuilder.Entity(entityType.ClrType)
.ToTable(tablePrefix + table.Name);

结合模式匹配语法,我们可以写出如下形式:

// 若table为null,模式匹配结果将为false
if (entityType.ClrType
.GetCustomAttributes(typeof(TableAttribute), true)
.FirstOrDefault() is TableAttribute table)
{
modelBuilder.Entity(entityType.ClrType)
.ToTable(tablePrefix + table.Name);
}

最后,还没有完!!

还记得在一开始,我就说了ABP Module Zero内置表有默认的前缀Abp,也就是说在上述反射获得的内置表table.Name将是Abpxxx的形式,如果你不希望表名中出现Abp,可以在反射之后再使用Abp提供的拓展方法将表名修改一下。

ABP框架入门踩坑-配置数据库表前缀的更多相关文章

  1. ABP框架入门踩坑-配置User Secrets

    配置User Secrets ABP踩坑记录-目录 起因 因为以往习惯在User Secrets中保存连接字符串之类信息,但当我把连接字符串移到secrets.json中后,却发现在迁移过程中会报如下 ...

  2. ABP框架入门踩坑-添加实体

    添加实体 ABP踩坑记录-目录 这里我以问答模块为例,记录一下我在创建实体类过程中碰到的一些坑. 审计属性 具体什么是审计属性我这里就不再介绍了,大家可以参考官方文档. 这里我是通过继承定义好的基类来 ...

  3. ABP框架入门踩坑-使用MySQL

    使用MySQL ABP踩坑记录-目录 起因 因为我自用的服务器只是腾讯云1核1G的学生机,不方便装SQL Server,所以转而MySQL. 这里使用的MySQL版本号为 8.0. 解决方案 删除Qi ...

  4. ABP框架源码学习之修改默认数据库表前缀或表名称

    ABP框架源码学习之修改默认数据库表前缀或表名称 1,源码 namespace Abp.Zero.EntityFramework { /// <summary> /// Extension ...

  5. 我的微信小程序入门踩坑之旅

    前言 更好的阅读体验请:我的微信小程序入门踩坑之旅 小程序出来也有一段日子了,刚出来时也留意了一下.不过赶上生病,加上公司里也有别的事,主要是自己犯懒,就一直没做.这星期一,赶紧趁着这股热乎劲,也不是 ...

  6. 【ABP框架系列学习】启动配置(5)

    ABP提供了在启动时配置模块的基础设施和模型. 1.配置ABP 配置ABP是在模块的PreInitialize方法中完成的,例如: public class SimpleTaskSystemModul ...

  7. 项目那几步走:先配置setting路径文件、创建数据库、执行数据库迁移命令、配置mysql数据库信息、注册app、注释中间件、pymysql替换mysqldb-配置urls路由-继续视图函数-然后HTML页面展示-HTML里面导入css文件、models配置数据库表、

    django使用mysql数据库: 首先cmd创建库 1.settings: """Django settings for day42 project. Generate ...

  8. Go ORM框架 - GORM 踩坑指南

    今天聊聊目前业界使用比较多的 ORM 框架:GORM.GORM 相关的文档原作者已经写得非常的详细,具体可以看这里,这一篇主要做一些 GORM 使用过程中关键功能的介绍,GORM 约定的一些配置信息说 ...

  9. Spark踩坑记——数据库(Hbase+Mysql)

    [TOC] 前言 在使用Spark Streaming的过程中对于计算产生结果的进行持久化时,我们往往需要操作数据库,去统计或者改变一些值.最近一个实时消费者处理任务,在使用spark streami ...

随机推荐

  1. SQL查找指定行的记录

    select top 1 * from (select top 4 * from T_GasStationPrice order by EnableTime) a order by EnableTim ...

  2. Spark Streaming性能调优详解

    Spark Streaming性能调优详解 Spark  2015-04-28 7:43:05  7896℃  0评论 分享到微博   下载为PDF 2014 Spark亚太峰会会议资料下载.< ...

  3. java测试ATM自助操作系统

    开学第一周系主任安排了一项测试,测试要求:模拟ATM自助取款机用文件进行存储账户信息,密码等,并进行存款取款,转账,查询记录等操作,而且要进行文件的读取与录入. 这是一个ATM自助取款的操作系统,进行 ...

  4. rails 表单中默认值

    在表单中加入默认提示值,如(email@email.com): <div class="field"> <%= form.label :email,"E ...

  5. sql number类型和varchar2类型

    查询时,发现org_id 为number类型,zone_id为varchar2类型,需要转化 转换 to_char(),或者to_number select a.id,b.col,a.col from ...

  6. (4)4 larger-than-life lessons from soap operas

    https://www.ted.com/talks/kate_adams_4_larger_than_life_lessons_from_soap_operas/transcript 00:12In ...

  7. Android APP测试流程

    一. Monkey测试(冒烟测试) 使用monkey测试工具进行如下操作: 1. APP的安装 2. APP随机操作测试(APP压力测试) 3. APP的卸载 二. 安装卸载测试 1. 使用测试真机进 ...

  8. 将批量指定的docker镜像打成文件

      #/bin/bash tag= img1=hub.chinacloud.com.cn/onex.dev/one-task-scheduler:$tag img2=hub.chinacloud.co ...

  9. c语言const和c++const

    1.常量 常量是指值不能被改变的量,又叫做字面值 1.1常量分类 1)字符常量:'a', 'A', '*'. 2)字符串常量:"helloworld","ilovechi ...

  10. s4-9 二层设备

    二层(数据链路层)设备有哪些?  网卡  网桥  交换机 NIC 网卡  Nework Interface Card  为主机提供介质的访问.  MAC地址烧在网卡的 ROM中 NIC 网 ...