X-Admin&ABP框架开发-数据字典
在业务型的系统开发中,我们需要维护各种个样的类型,比如客户类型、客户行业、商品类型等等,这些类型往往信息量不多,并且相似度极高,如果采用一类型一表去设计,将会造成极大的工作量,通过将这部分类型的信息进行抽象,利用字段去存储类型区分,共用表结构,来达到兼容各种类型的功能,也就是设计一个数据字典,而对于一个具体类型来讲,是有多个选项的,比如性别,有男女,行业有工农商等,对于这部分选项,可抽象为某个类型下的字典项,即数据字典项。
一、数据字典设计思路
1、从客户类型、商品类型、行业类型来抽象考虑,首先三者都存在一个类型描述,即客户、商品、行业,同时,三者是本质是不同的,并且,随着业务上的需求越来越多,更多的xx类型将会加入,因此,单从类型考虑出发,就存在三个点了,如类型名称、类型独立、数量扩展,因此在考虑表结构设计时,就可以先考虑到这三点了,同时还有一个关键的信息,便是,在系统设计过程中,这些类型其实便已经确定完毕了,而不是说,在开发完毕,再去系统中增加类型。
2、从具体的某个类型出发考虑,比如以商品类型为例,存在日用品、电子产品、化妆品等,同样是存在几个关键信息,比如类型项名称、类型项独立、类型项数量扩展,类型项的归属,而这部分信息,往往是由客户去维护的,属于系统开发完毕后期的信息维护,在此,不考虑类型项的先后顺序问题,如有需要可以扩展。
按照这些信息点,可以对数据字典设计一些必要的字段,如类型名称即TypeName、 类型独立便是类型间相互独立,但是这里也存在一个类型间的上下父子问题,暂不加入进来,该父子问题使用场景较少,但又存在,如果按照“二八原则”的话,我还是喜欢把“八”的部分完成。对于数据字典项而言,按照给定的必要信息,设计成如下结构,其中的业务代码,是需要唯一的,比如对于性别来将,业务代码便是1或0,来代表男女,这部分可由客户的系统管理员进行维护。
二、完成数据字典设计
在明确了这些基础信息后,开始在项目中完成设计过程,首先得明确数据字典本身的归属,数据字典是为整个业务而服务的,因此我把它划分到核心层这一级别中,首先在领域层设置Core层文件夹,用来存放为整个业务提供基础设施的功能模块。
1、在Core层中加入数据字典模块,结构设计如:
开始创建数据字典类,并添加设计的字段,以保证够用为前提,或许更多场景下会出现诸如父子字典情形,或是对字典内容的描述等,暂不考虑。
/// <summary>
/// 核心_数据字典
/// </summary>
[Table("Core_DataDictionary")]
public class DataDictionary : Entity<long>
{
public const int MaxNameLength = ; /// <summary>
/// 字典类型
/// </summary>
[StringLength(MaxNameLength)]
public string TypeName { get; set; } /// <summary>
/// 关联数据字典项
/// </summary>
public virtual ICollection<DataDictionaryItem> DataDictionaryItem { get; set; }
}
在增加数据字典项类,并添加设计时的字段信息,这里我通过数据注解完成对字段的一些约束,如长度约束,表名的映射等。
/// <summary>
/// 核心_数据字典项
/// </summary>
[Table("Core_DataDictionaryItem")]
public class DataDictionaryItem : Entity<long>
{
public const int MaxCodeLength = ;
public const int MaxNameLength = ; /// <summary>
/// 业务代码
/// </summary>
[StringLength(MaxCodeLength)]
public string Code { get; set; } /// <summary>
/// 类型项名称
/// </summary>
[StringLength(MaxNameLength)]
public string Name { get; set; } /// <summary>
/// 数据字典Id
/// </summary>
public long DataDictionaryId { get; set; } /// <summary>
/// 关联数据字典项
/// </summary>
public virtual DataDictionary DataDictionary { get; set; }
}
加入到DbContext中,添加一个迁移并更新数据库。
2、开始完成应用层的封装工作,在应用层定义了几个常用的对字典的一些操作,诸如添加删除修改等常见操作,此处的数据字典暂时通过手动加入,而不是将已有数据字典或是更改了的数据字典自动更新到数据库中。
/// <summary>
/// 获取数据字典集合
/// </summary>
/// <returns></returns>
Task<ListResultDto<DataDictionaryListDto>> GetAllDataDictionaryListAsync(); /// <summary>
/// 获取数据字典记录
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task<DataDictionaryEditDto> GetDataDictionaryForEditAsync(NullableIdDto<long> input); /// <summary>
/// 添加或更新数据字典记录
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task CreateOrUpdateDataDictionaryAsync(CreateOrUpdateDataDictionaryInput input); /// <summary>
/// 删除数据字典记录
/// </summary>
/// <param name="ids"></param>
/// <returns></returns>
Task DeleteDataDictionaryAsync(List<EntityDto<long>> inputs); /// <summary>
/// 根据字典类型名称获取数据字典集合
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task<ListResultDto<DataDictionaryListDto>> GetDataDictionaryListByTypeNamesAsync(GetDataDictionaryListByTypeNamesInput input);
对数据字典项也准备了几个方法,用于对某一具体数据字典类型增加删除修改数据字典项。
/// <summary>
/// 获取数据字典项
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task<DataDictionaryItemEditDto> GetDataDictionaryItemForEditAsync(NullableIdDto<long> input); /// <summary>
/// 添加或更新数据字典项
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task CreateOrUpdateDataDictionaryItemAsync(CreateOrUpdateDataDictionaryItemInput input); /// <summary>
/// 删除数据字典项
/// </summary>
/// <param name="ids"></param>
/// <returns></returns>
Task DeleteDataDictionaryItemAsync(List<EntityDto<long>> inputs); /// <summary>
/// 根据字典类型和字典项名称获取字典项值
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task<GetDataDictionaryItemNameOutput> GetDataDictionaryItemNameAsync(GetDataDictionaryItemNameInput input); /// <summary>
/// 获取数据字典列表
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task<ListResultDto<DataDictionaryItemListDto>> GetDataDictionaryItemListAsync(GetDataDictionaryItemListInput input);
在应用层建立一个全局常量数据字典类,用于存储数据字典信息,该部分信息也将成为需要维护到系统中的必备信息,并且,在系统中如有地方需要调用到数据字典类型时,不需要写死代码。
/// <summary>
/// 数据字典类型存储表
/// </summary>
public class DataDictionaryTypeConsts
{
#region 分瓶规则
public const string GroupRule_FixAtive = "固定剂及使用"; public const string GroupRule_ContainerType = "容器类型";
#endregion
}
3、完成控制器层调用及页面中对数据字典的管理 ,对于字典信息而言,足够在界面中一览全貌,因此页面设计时,直接以树形结构加表格展示即可,左侧数据类型树形结构,右侧相应的数据类型项表格。
<div class="layui-row">
<div class="layui-col-md2 layui-col-xs12">
<ul id="tree" class="ztree" style="padding: 0px; border: 1px solid #ddd; overflow: auto;"></ul>
</div>
<div class="layui-col-md10 layui-col-xs12">
<table class="layui-table"
lay-data="{height: 'full-180', page:true, id:'mainList'}"
lay-filter="list" lay-size="xs">
<thead>
<tr>
<th lay-data="{checkbox:true, fixed: true}"></th>
<th lay-data="{field:'code', sort: true}">业务代码</th>
<th lay-data="{field:'name'}">名称</th>
@if (await PermissionChecker.IsGrantedAsync(PermissionNames.Pages_Core_DataDictionaryItem_Edit) ||
await PermissionChecker.IsGrantedAsync(PermissionNames.Pages_Core_DataDictionaryItem_Delete))
{
<th lay-data="{fixed:'right', align:'center', toolbar: '#barList'}"></th>
}
</tr>
</thead>
</table>
</div>
</div>
三、数据字典页面展示
利用layui节省了不少时间,对于前端东西不太精通,只能够用,勉强实现了数据字典的一些操作,其中的数据字典类型是按照开发过程中可能用到的进行加入的,合理的存在,而不是空穴来风,在之前的DataDictionaryConst类中可以定义需要用到的数据字典类型,此处并没有直接从那里增加后自动导入到数据库中。
至此,数据字典的初步逻辑设计完毕,至于要加入更为丰富的功能,诸如排序,父子数据类型,或是数据类型描述,均可扩展。
代码地址:https://gitee.com/530521314/Partner.Surround.git
2019-07-07,望技术有成后能回来看见自己的脚步
X-Admin&ABP框架开发-数据字典的更多相关文章
- X-Admin&ABP框架开发-消息通知
业务型网站使用过程中,消息通知是一个不可或缺的功能,采用站内通知.短信通知.邮件通知.微信通知等等各种方式都有,ABP框架对这部分工作已经封装的很好了,站在巨人的肩膀上,一览全貌,带来的就是心情舒畅. ...
- X-Admin&ABP框架开发-系统日志
网站正常运行中有时出现异常在所难免,查看系统运行日志分析问题并能够根据错误信息快速解决问题尤为重要,ABP对于系统运行日志这块已经做了很好的处理,默认采用的Log4Net已经足够满足开发过程中的需要了 ...
- X-Admin&ABP框架开发-版本管理
多租户系统中,针对于不同租户开放不同功能,或是按照不同功能进行收费管理,需要从宿主本身去管理租户的版本信息,如同酒店人员对不同房间收取不同费用,依据房间内部设施,房间大小等设置不同收费标准.Abp系统 ...
- X-Admin&ABP框架开发-代码生成器
在日常开发中,有时会遇到一些相似的代码,甚至是只要CV一次,改几个名称,就可以实现功能了,而且总归起来,都可以由一些公用的页面更改而来,因此,结合我日常开发中使用到的页面,封装一个适合自己的代码生成器 ...
- X-Admin&ABP框架开发-设置管理
在网站开发中,设置是不可缺少的一环,如用户设置.系统设置.甚至是租户设置等.ABP对于设置的管理已经做了很好的处理,我们可以借助巨人的力量来完成我们的冒险. ABP官网地址:https://aspne ...
- X-Admin&ABP框架开发-RBAC
在业务系统需求规划过程中,通常对于诸如组织机构.用户和角色等这种基础功能,通常是将这部分功能规划到通用子域中,这也说明了,对于这部分功能来讲,是系统的基石,整个业务体系是建立于这部分基石之上的,当然, ...
- X-Admin&ABP框架开发-租户管理
软件即服务概念的推动,定制化到通用化的发展,用一套代码完成适应不同企业的需求,利用多租户技术可以去做到这一点.ABP里提供了多租户这一概念并且也在Zero模块中实现了这一概念. 一.多租户的概念 单部 ...
- ABP开发框架前后端开发系列---(8)ABP框架之Winform界面的开发过程
在前面随笔介绍的<ABP开发框架前后端开发系列---(7)系统审计日志和登录日志的管理>里面,介绍了如何改进和完善审计日志和登录日志的应用服务端和Winform客户端,由于篇幅限制,没有进 ...
- ABP开发框架前后端开发系列---(15)ABP框架的服务端和客户端缓存的使用
缓存在一个大型一点的系统里面是必然会涉及到的,合理的使用缓存能够给我们的系统带来更高的响应速度.由于数据提供服务涉及到数据库的相关操作,如果客户端的并发数量超过一定的数量,那么数据库的请求处理则以爆发 ...
随机推荐
- 浅谈C/C++堆栈指引——C/C++堆栈很强大(绝美)
C/C++堆栈指引 Binhua Liu 前言 我们经常会讨论这样的问题:什么时候数据存储在飞鸽传书堆栈(Stack)中,什么时候数据存储在堆(Heap)中.我们知道,局部变量是存储在堆栈中的:deb ...
- 多线程——继承Thread类别
详细java此前使用多线程,让我们来看看下面的问题. 什么是多线程 简单的理解成:cpu"同一时候"运行多个任务,这就是多线程. (究其本质,当涉及到进程和线程的概念.上面 ...
- log4net使用记录
1.在程序中引用log4net.dll 2.添加-新建配置文件Log4Net.config,并在文件属性中“复制到输出目录”选中“始终复制”,文件内容如下: <?xml version=&quo ...
- Logback 专题
logback-spring.xml <?xml version="1.0" encoding="UTF-8"?> <configuratio ...
- 更新EF(更新表 添加表…)
- PostMessage和SendMessage有什么区别?(有EnumChildWindowsProc的例子)
PostMessage只是把消息放入队列,不管其他程序是否处理都返回,然后继续执行;而SendMessage必须等待其他程序处理消息后才返回,继续执行.PostMessage的返回值表示PostMes ...
- Python标准库(3.x): 内建函数扫盲
Built-in Functions abs() dict() help() min() setattr() all() dir() hex() next() slice() any() divmod ...
- 同城快递公司Postmates近日完成1亿美元融资,美国外卖餐饮迎来一波融资热潮
美国外卖市场尚未出现一家独大的巨头,一部分原因是与中国的外卖平台相比,在美国,外卖平台要克服的难题可能更多. 4个月之前才完成3亿美元融资的美国同城快递公司Postmates近日又完成1亿美元融资,估 ...
- 正则表达式-Csharp
原文:正则表达式-Csharp 学习笔记:正则表达式 一. 正则表达式 正则表达式(Regex)是用来进行文本处理的技术,是语言无关的,在几乎所有语言中都有实现. 一个正则表达式就是由普通的字符及特殊 ...
- RxJava入门优秀博客推荐
RxJava用了快半年了,现在越来越离不开这个库,从使用到逐渐接触它的背后实现,突然想写点什么关于RxJava的内容.在酝酿如何组织内容的时候,就去看看自己关于RxJava的收藏,发现满满的干货! 1 ...