博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ABP框架入门踩坑-配置数据库表前缀
阅读量:5377 次
发布时间:2019-06-15

本文共 2761 字,大约阅读时间需要 9 分钟。

配置数据库表前缀

本篇其实和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
(tablePrefix);}

经历

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

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

参考资料:

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

可以参考以下代码:

// 这里tablePrefix为字符串常量modelBuilder.Entity
().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,模式匹配结果将为falseif (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提供的拓展方法将表名修改一下。

转载于:https://www.cnblogs.com/yiluomyt/p/10350524.html

你可能感兴趣的文章
参数展示初始三层架构
查看>>
项目视频光盘项目中所学概览-html5+批处理+bat转exe
查看>>
hdu 1028
查看>>
思考技术 (一) —— 什么是新技术
查看>>
ubuntu更改源为aliyun的源;ROS改为新加坡源
查看>>
正则表达式入门
查看>>
Halcon标定与自标定
查看>>
Non-local Neural Networks
查看>>
apache Internal Server Error 解决方法
查看>>
Ubuntu14.04安装CUDA8.0与Cudnn5.1
查看>>
(七)STM32的RTC简单操作
查看>>
Floyd最短路算法
查看>>
【转】Java并发编程:并发容器之ConcurrentHashMap
查看>>
IIS
查看>>
thinkphp5.0独立配置
查看>>
day2逻辑运算作业详解
查看>>
JQuery将DataTable list<>数据转换成JSON数据 动态创建表格显示数据
查看>>
MySQL中的information_schema
查看>>
一般路由设置
查看>>
JS 无法清除Cookie的解决方法
查看>>