在業務型的系統開發中,咱們須要維護各類個樣的類型,好比客戶類型、客戶行業、商品類型等等,這些類型每每信息量很少,而且類似度極高,若是採用一類型一表去設計,將會形成極大的工做量,經過將這部分類型的信息進行抽象,利用字段去存儲類型區分,共用表結構,來達到兼容各類類型的功能,也就是設計一個數據字典,而對於一個具體類型來說,是有多個選項的,好比性別,有男女,行業有工農商等,對於這部分選項,可抽象爲某個類型下的字典項,即數據字典項。前端
一、從客戶類型、商品類型、行業類型來抽象考慮,首先三者都存在一個類型描述,即客戶、商品、行業,同時,三者是本質是不一樣的,而且,隨着業務上的需求愈來愈多,更多的xx類型將會加入,所以,單從類型考慮出發,就存在三個點了,如類型名稱、類型獨立、數量擴展,所以在考慮表結構設計時,就能夠先考慮到這三點了,同時還有一個關鍵的信息,即是,在系統設計過程當中,這些類型其實便已經肯定完畢了,而不是說,在開發完畢,再去系統中增長類型。java
二、從具體的某個類型出發考慮,好比以商品類型爲例,存在日用品、電子產品、化妝品等,一樣是存在幾個關鍵信息,好比類型項名稱、類型項獨立、類型項數量擴展,類型項的歸屬,而這部分信息,每每是由客戶去維護的,屬於系統開發完畢後期的信息維護,在此,不考慮類型項的前後順序問題,若有須要能夠擴展。git
按照這些信息點,能夠對數據字典設計一些必要的字段,如類型名稱即TypeName、 類型獨立即是類型間相互獨立,可是這裏也存在一個類型間的上下父子問題,暫不加入進來,該父子問題使用場景較少,但又存在,若是按照「二八原則」的話,我仍是喜歡把「八」的部分完成。對於數據字典項而言,按照給定的必要信息,設計成以下結構,其中的業務代碼,是須要惟一的,好比對於性別來將,業務代碼即是1或0,來表明男女,這部分可由客戶的系統管理員進行維護。數據庫
在明確了這些基礎信息後,開始在項目中完成設計過程,首先得明確數據字典自己的歸屬,數據字典是爲整個業務而服務的,所以我把它劃分到核心層這一級別中,首先在領域層設置Core層文件夾,用來存放爲整個業務提供基礎設施的功能模塊。ui
一、在Core層中加入數據字典模塊,結構設計如:spa
開始建立數據字典類,並添加設計的字段,以保證夠用爲前提,或許更多場景下會出現諸如父子字典情形,或是對字典內容的描述等,暫不考慮。設計
/// <summary> /// 核心_數據字典 /// </summary> [Table("Core_DataDictionary")] public class DataDictionary : Entity<long> { public const int MaxNameLength = 30; /// <summary> /// 字典類型 /// </summary> [StringLength(MaxNameLength)] public string TypeName { get; set; } /// <summary> /// 關聯數據字典項 /// </summary> public virtual ICollection<DataDictionaryItem> DataDictionaryItem { get; set; } }
在增長數據字典項類,並添加設計時的字段信息,這裏我經過數據註解完成對字段的一些約束,如長度約束,表名的映射等。3d
/// <summary> /// 核心_數據字典項 /// </summary> [Table("Core_DataDictionaryItem")] public class DataDictionaryItem : Entity<long> { public const int MaxCodeLength = 5; public const int MaxNameLength = 30; /// <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中,添加一個遷移並更新數據庫。code
二、開始完成應用層的封裝工做,在應用層定義了幾個經常使用的對字典的一些操做,諸如添加刪除修改等常見操做,此處的數據字典暫時經過手動加入,而不是將已有數據字典或是更改了的數據字典自動更新到數據庫中。blog
/// <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 }
三、完成控制器層調用及頁面中對數據字典的管理 ,對於字典信息而言,足夠在界面中一覽全貌,所以頁面設計時,直接以樹形結構加表格展現便可,左側數據類型樹形結構,右側相應的數據類型項表格。
<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,望技術有成後能回來看見本身的腳步