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框架入门踩坑-配置数据库表前缀的更多相关文章
- ABP框架入门踩坑-配置User Secrets
配置User Secrets ABP踩坑记录-目录 起因 因为以往习惯在User Secrets中保存连接字符串之类信息,但当我把连接字符串移到secrets.json中后,却发现在迁移过程中会报如下 ...
- ABP框架入门踩坑-添加实体
添加实体 ABP踩坑记录-目录 这里我以问答模块为例,记录一下我在创建实体类过程中碰到的一些坑. 审计属性 具体什么是审计属性我这里就不再介绍了,大家可以参考官方文档. 这里我是通过继承定义好的基类来 ...
- ABP框架入门踩坑-使用MySQL
使用MySQL ABP踩坑记录-目录 起因 因为我自用的服务器只是腾讯云1核1G的学生机,不方便装SQL Server,所以转而MySQL. 这里使用的MySQL版本号为 8.0. 解决方案 删除Qi ...
- ABP框架源码学习之修改默认数据库表前缀或表名称
ABP框架源码学习之修改默认数据库表前缀或表名称 1,源码 namespace Abp.Zero.EntityFramework { /// <summary> /// Extension ...
- 我的微信小程序入门踩坑之旅
前言 更好的阅读体验请:我的微信小程序入门踩坑之旅 小程序出来也有一段日子了,刚出来时也留意了一下.不过赶上生病,加上公司里也有别的事,主要是自己犯懒,就一直没做.这星期一,赶紧趁着这股热乎劲,也不是 ...
- 【ABP框架系列学习】启动配置(5)
ABP提供了在启动时配置模块的基础设施和模型. 1.配置ABP 配置ABP是在模块的PreInitialize方法中完成的,例如: public class SimpleTaskSystemModul ...
- 项目那几步走:先配置setting路径文件、创建数据库、执行数据库迁移命令、配置mysql数据库信息、注册app、注释中间件、pymysql替换mysqldb-配置urls路由-继续视图函数-然后HTML页面展示-HTML里面导入css文件、models配置数据库表、
django使用mysql数据库: 首先cmd创建库 1.settings: """Django settings for day42 project. Generate ...
- Go ORM框架 - GORM 踩坑指南
今天聊聊目前业界使用比较多的 ORM 框架:GORM.GORM 相关的文档原作者已经写得非常的详细,具体可以看这里,这一篇主要做一些 GORM 使用过程中关键功能的介绍,GORM 约定的一些配置信息说 ...
- Spark踩坑记——数据库(Hbase+Mysql)
[TOC] 前言 在使用Spark Streaming的过程中对于计算产生结果的进行持久化时,我们往往需要操作数据库,去统计或者改变一些值.最近一个实时消费者处理任务,在使用spark streami ...
随机推荐
- ubuntu系统ftp连接 以及ssh连接
tfp连接 ssh连接 ubuntu下ssh使用 与 SCP 使用 1 ssh远程登录服务器 ssh username@remote_ip #将username换成自己的用户名,将remote_ip换 ...
- 使用yarn 安装 Vue-DevTools
1. 从 github 下载 vuejs/vue-devtools https://github.com/vuejs/vue-devtools/archive/dev.zip 2.安装yarn 及 编 ...
- SharePoint 开发小结
目标:将sharepoint网站对接Office 365 最直接的API:How to: Add Office 365 APIs to a Visual Studio project http://m ...
- Mysql #1406 Data too long 错误
Mysql #1406 Data too long 错误 http://blog.sina.com.cn/s/blog_68004f680100kgfh.html B. Mysql配置文件: “在 ...
- mysql 批量杀进程
select concat('KILL ',id,';') from information_schema.processlist where user='root';
- 2018.11.28 poj3294 Life Forms(后缀数组+双指针)
传送门 后缀数组经典题目. 我们先把所有的字符串都接在一起. 然后求出hththt数组和sasasa数组. 然后对于sasasa数组跑双指针统计答案. 如果双指针包括进去的属于不同字符串的数量达到了题 ...
- 虚拟机 与 主机 Ping 中的设置
这段时间是学习华清远见的Linux A8 关于Linux移植,遇到虚拟机与主机Ping不通.经查阅后总结出以下 VM中设置. “虚拟机设置-->硬件--> 网络适配器--> 桥接模式 ...
- openstack网络基本概念(转)
OpenStack的Neutron能够管理OpenStack环境中的虚拟 网络基础设施(VNI).和物理网络基础设施(PNI). OpenStack的Neutron同意租户创建虚拟网络拓扑结构.包括的 ...
- 移动赋值运算符(c++11)
1.概念 1)移动赋值运算符是一个重载的赋值运算符,参数为自身类的右值引用,返回值自身类的左值引用,由于不抛出任何异常,用noexcept指定(如果定义在类的外面,那么定义也要用noexcept指定) ...
- c# 文件笔记
1.文件属性操作 File类与FileInfo都能实现.静态方法与实例化方法的区别! //use File class Console.WriteLine(File.GetAttributes(fil ...