基于SQLite+EF6实现一套自己的Key-Value存储管理工具包(1)

在项目中,经常会需要对一些特定的业务对象进行属性的扩展,而且这些属性的扩展还具备极不可预测性、相互关系松散等特点。大部分的开发人员是最讨厌这类涉及到数据字段扩展的需求变更。这种调整,轻则数据要加字段,重则程序代码要做大量的调整。在几微助手的开发过程中,也会涉及大量的类似需求的变更、扩展,甚至随着业务发展,自然就有大量的新的东东需要进行扩展。不需要在修改数据库字段、增加字段/属性后不需要大范围的代码调整合,可以根据业务需求改变储存5、未来的扩展开发只需要关注属性扩展可以业务逻辑,无需重复底层的数据开发

基于以上目标,我们初步在整理一下开发/设计思路:预定义代码级扩展配置文件扩展,理论上支持这三种方式,后期的代码维护就简单了

好了下面开始!先做好数据库设计:

640?wx_fmt=png

这里很简单,数据库里面就两张表(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)其实用系统默认提供的一些字典对象也可以干,不过我比较喜欢强类型,这里就全自己定义个类型,在代码里面看到这个东东就知道这个玩意是我自己的一个扩展属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/// <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 );
      }
 
  }

为字典对象的单项定义一个强类型结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/// <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 ; }
 
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值