基于SQLite+EF6实现一套自己的Key-Value存储管理工具包(1)
在項目中,經常會需要對一些特定的業務對象進行屬性的擴展,而且這些屬性的擴展還具備極不可預測性、相互關系松散等特點。大部分的開發人員是最討厭這類涉及到數據字段擴展的需求變更。這種調整,輕則數據要加字段,重則程序代碼要做大量的調整。在幾微助手的開發過程中,也會涉及大量的類似需求的變更、擴展,甚至隨著業務發展,自然就有大量的新的東東需要進行擴展。不需要在修改數據庫字段、增加字段/屬性后不需要大范圍的代碼調整合,可以根據業務需求改變儲存5、未來的擴展開發只需要關注屬性擴展可以業務邏輯,無需重復底層的數據開發
基于以上目標,我們初步在整理一下開發/設計思路:預定義、代碼級擴展、配置文件擴展,理論上支持這三種方式,后期的代碼維護就簡單了
好了下面開始!先做好數據庫設計:
這里很簡單,數據庫里面就兩張表(SettingExtensions:通用擴展表,ModuleItemSettiingExtensions:單項個別擴展表),這里我們線建立一個概念,將所有擴展看做是原主體對象的設置。另外,有些主體對象可能還是一個集合,例如產品,那么這里我們可以把全部產品的管理當成一個主模塊,對于這個主模塊,可能會有需要擴展的通用的屬性,那么在這個模塊內的每個產品項(這里我們展示叫ModuleItem)還會有自己的單獨擴展項,可能是從通用繼承,可能是特殊的。
所以數據庫就這兩張表,一張放通用、一張放個別,如果需要開發的對象無所謂通用、個別的關系,那么我就統一放在SettingExtensions。關于字段,就比較簡單了,主要是Key,Value字段,value是一個長文本字段,便于未來可以存放json、轉成base64的二進制等復雜對象。另外在SettingExtensions里面多了一個TypeName,這個主要是區別一下模塊類型名稱,眾多模塊如果放在一個數據庫,Key是有可能重復的。在ModuleItemSettiingExtensions表里面,ModuleType是記錄當前個別項所屬的集合類型名,同SettingExtensions->TypeName,ModuleItemID就是當前Item主體在系統中的唯一ID,例如:這個項是擴展產品的屬性,那這里就應該是產品ID
開始寫代碼,先自定義以個Key-Value的對象,這里我們從DictionaryBase繼承,在此基礎上擴展,主要是忽略掉Key的大小寫(我不喜歡大小寫敏感的Key)其實用系統默認提供的一些字典對象也可以干,不過我比較喜歡強類型,這里就全自己定義個類型,在代碼里面看到這個東東就知道這個玩意是我自己的一個擴展屬性。
| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 | /// <summary>?/// 自定義設置的字典對象,繼承DictionaryBase,?/// 在SettingDictionary實現中索引或者設置鍵值對,對鍵key的大小寫不敏感?/// </summary>?public class SettingDictionary:DictionaryBase?{?????public event ItemChanged OnItemChanged;?????/// <summary>?????/// 添加鍵值對到hashtable?????/// </summary>?????/// <param name="key"></param>?????/// <param name="value"></param>?????public virtual void Add(string key,?string value)?????{?????????this.InnerHashtable.Add(key.ToLower(), value);?????}?????/// <summary>?????/// 獲取或設置鍵值對中的值?????/// </summary>?????/// <param name="key"></param>?????/// <returns></returns>?????public string this[string key]?????{?????????get?????????{?????????????return (string)this.InnerHashtable[key.ToLower()];?????????}?????????set?????????{?????????????if (this.ContainsKey(key) || !this.InnerHashtable[key.ToLower()].Equals(value))?????????????{?????????????????if (this.OnItemChanged !=?null)?????????????????????this.OnItemChanged(this, key);?????????????}?????????????this.InnerHashtable[key.ToLower()] = value;?????????}?????}?????/// <summary>?????/// 判斷關鍵字是否存在?????/// </summary>?????/// <param name="key"></param>?????/// <returns></returns>?????public bool ContainsKey(string key)?????{?????????return this.InnerHashtable.ContainsKey(key.ToLower());?????}?????private class SettingDictionaryEnumerator : IDictionaryEnumerator?????{?????????DictionaryEntry[] items;?????????Int32 index = -1;?????????public SettingDictionaryEnumerator(SettingDictionary settings)?????????{?????????????items =?new DictionaryEntry[settings.Count];?????????????settings.CopyTo(items, 0);?????????????//items.OrderBy(m => m.Key);?????????????//Array.Reverse(items);?????????}?????????// 返回當前項?????????public Object Current {?get { ValidateIndex();?return new SettingItem { Key = items[index].Key.ToString(), Value = items[index].Value.ToString() }; } }?????????// 返回當前字典實例?????????public DictionaryEntry Entry?????????{?????????????get {?return (DictionaryEntry)Current; }?????????}?????????// 返回當前項的Key?????????public Object Key {?get { ValidateIndex();?return items[index].Key; } }?????????// 返回當前項目的Value?????????public Object Value {?get { ValidateIndex();?return items[index].Value; } }?????????public Boolean MoveNext()?????????{?????????????if (index < items.Length - 1) { index++;?return true; }?????????????return false;?????????}?????????private void ValidateIndex()?????????{?????????????if (index < 0 || index >= items.Length)?????????????????throw new InvalidOperationException("超出項目索引邊界");?????????}?????????public void Reset()?????????{?????????????index = -1;?????????}?????}?????public IDictionaryEnumerator GetEnumerator()?????{?????????return new SettingDictionaryEnumerator(this);?????}?} | 
為字典對象的單項定義一個強類型結構:
| 12345678910111213141516 | /// <summary>/// 設置項目的結構/// </summary>public struct SettingItem{????private string _key;????/// <summary>????/// 設置實例的鍵(名稱)????/// </summary>????public string Key {?get {?return this._key.ToLower(); }?set {?this._key = value.ToLower(); } }????/// <summary>????/// 設置實例的值????/// </summary>????public string Value {?get;?set; }} | 
?
總結
以上是生活随笔為你收集整理的基于SQLite+EF6实现一套自己的Key-Value存储管理工具包(1)的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 基于SQLite+EF6实现一套自己的K
 - 下一篇: 【C】Natasha V1.3.6.0