基于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 { getset; }
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/314052.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2019-03-09-算法-进化(买卖股票的最佳时机 II)

题目描述 给定一个数组&#xff0c;它的第 i 个元素是一支给定股票第 i 天的价格。 设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易&#xff08;多次买卖一支股票&#xff09;。 注意&#xff1a;你不能同时参与多笔交易&#xff08;你必须在再次购买…

【C】Natasha V1.3.6.0 的升级日志

文章转载授权级别&#xff1a;C 预计阅读时间&#xff1a;8分钟开源库满足于个人&#xff0c;而完善于大众。Natasha 自稳定版发布之后&#xff0c;众多老铁参与增强改进&#xff0c;感谢如下老铁的反馈&#xff1a;1. 异常搜集在 wenjq0911 建议下&#xff0c;添加…

牛客练习赛69 解方程

解方程 ∑d∣nf(d)σp(nd)σq(n)f∗σpσq有σk∑d∣ndkidk∗If∗idp∗Iidq∗I∑d∣nμ(d)μ∗I对上面式子同时卷上一个μf∗idpidq因为idk是一个完全积性函数&#xff0c;所以idp−1μidpidk∗(μidp)∑d∣ndkμ(nd)(nd)k∑d∣nμ(d)ϵfidq∗(μidp)f(n)∑d∣nμ(d)dp(nd)qf(1…

2019-03-09-算法-进化(旋转数组)

题目描述 给定一个数组&#xff0c;将数组中的元素向右移动 k 个位置&#xff0c;其中 k 是非负数。 示例 1: 输入: [1,2,3,4,5,6,7] 和 k 3 输出: [5,6,7,1,2,3,4] 解释: 向右旋转 1 步: [7,1,2,3,4,5,6] 向右旋转 2 步: [6,7,1,2,3,4,5] 向右旋转 3 步: [5,6,7,1,2,3,4]示…

.NET 程序员如何学习Vue

之所以取这个标题&#xff0c;是因为本文来自内部培训的整理&#xff0c;培训的对象是公司的 .NET 程序员&#xff0c;.NET 程序员学习 Vue 是为了在项目中做二次开发时能够更好地跟产品对接。Vue 是现在比较流行的前端框架&#xff0c;也是非常容易入门的前端框架&#xff0c;…

P3714 [BJOI2017]树的难题(点分治/线段树/单调队列)

P3714 [BJOI2017]树的难题 求解树上长度在L到R的树链中颜色段权值和最大的链。 首先求解树上链的问题&#xff0c;而且限制了链的长度&#xff0c;那么我们需要点分治处理&#xff0c;然后考虑每次分治&#xff0c;我们可以把链分成两类&#xff0c;先处理同色连通块&#xf…

A Simple Math Problem(2020 ICPC 江西省省赛)

A Simple Math Problem ∑i1n∑j1if(j)[gcd(i,j)1]∑i1n∑jinf(i)[gcd(i,j)1]∑i1n∑j1nf(i)[gcd(i,j)1]−∑i1n∑j1if(i)[gcd(i,j)1]f(1)∑d1nμ(d)nd∑i1ndf(id)−∑i1nf(i)ϕ(i)f(1)然后就可以O(nlog⁡n)求解了\sum_{i 1} ^{n} \sum_{j 1} ^{i} f(j)[gcd(i, j) 1]\\ \sum…

2019-03-10-算法-进化(存在重复)

给定一个整数数组&#xff0c;判断是否存在重复元素。 如果任何值在数组中出现至少两次&#xff0c;函数返回 true。如果数组中每个元素都不相同&#xff0c;则返回 false。 示例 1: 输入: [1,2,3,1] 输出: true示例 2: 输入: [1,2,3,4] 输出: false示例 3: 输入: [1,1,1,…

P3233 [HNOI2014]世界树(虚树/倍增/动态规划)

P3233 [HNOI2014]世界树 每次给出mi个点&#xff0c;查询每个点控制的点的个数&#xff0c;每个点由离他最近编号最小的点控制。 首先按照套路建出虚树&#xff0c;注意特判1节点&#xff0c;然后用栈维护右链&#xff0c;然后不断弹栈建边。 然后进行dp&#xff0c;求解出虚…

.Net之微信小程序获取用户UnionID

前言&#xff1a;在实际项目开发中我们经常会遇到账号统一的问题&#xff0c;如何在不同端或者是不同的登录方式下保证同一个会员或者用户账号唯一&#xff08;便于用户信息的管理&#xff09;。这段时间就有一个这样的需求&#xff0c;之前有个客户做了一个微信小程序商城&…

Absolute Math (HDU 6868)

Absolute Math 定义c(n)theprimenhave&#xff0c;c(1)0,c(2)1,c(4)1,c(6)2f(n)∑d∣nμ(d)22c(n)f(ab)f(a)f(b)f(gcd(a,b))∑i1mf(n)f(i)f(gcd(n,i))f(n)∑d∣n1f(d)∑i1mdf(id)[gcd(i,nd)1]f(n)∑d∣n1f(d)∑k∣ndμ(k)∑i1mkdf(ikd)Tkdf(n)∑T∣n∑i1mTf(iT)∑d∣Tμ(Td)f(d…

2019-03-10-算法-进化(只出现一次的数字)

题目描述 给定一个非空整数数组&#xff0c;除了某个元素只出现一次以外&#xff0c;其余每个元素均出现两次。找出那个只出现了一次的元素。 说明&#xff1a; 你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗&#xff1f; 示例 1: 输入: [2,2,1] 输出: 1…

自由源自于自律 及其他三则分享

Office 365 官方公众号的新创深度内容推荐竹板这么一打呀&#xff0c;别的咱不夸&#xff0c;单说我们的Office 365官方公众号&#xff08;“微软Office365”&#xff09;&#xff0c;近一段时间来在内容创作上面有一些新的突破——推出了一个关于探讨大脑及思维运作的专题。请…

CF871E Restore the Tree(构造/哈希)

CF871E Restore the Tree 对于一个n个点的树&#xff0c;给定k个点以及这k个点到n个点的距离&#xff0c;然后构造出一颗合法的树。如果不存在合法的树输出-1&#xff0c;任意输出一组解即可。 首先处理在关键点链上的节点&#xff0c;对于两个关键点&#xff0c;有且仅有他们…

Battlestation Operational HDU 6134

Battlestation Operational ∑i1n∑j1i⌈ij⌉[gcd(i,j)1]∑i1n∑j1i(ij1)[gcd(i,j)1]−∑i1n∑j1i[gcd(i,j)1,j∣i]∑i1n∑j1i(ij1)[gcd(i,j)1]−n∑i1n∑j1iij[gcd(i,j)1]∑i1n∑j1i[gcd(i,j)1]−n∑i1n∑j1iij[gcd(i,j)1]∑i1ϕ(i)−n∑i1n∑j1iij[gcd(i,j)1]∑d1nμ(d)∑i1n…

2019-03-11-算法-进化(求众数)

题目描述 给定一个大小为 n 的数组&#xff0c;找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的&#xff0c;并且给定的数组总是存在众数。 示例 1: 输入: [3,2,3] 输出: 3示例 2: 输入: [2,2,1,1,1,2,2] 输出: 2思路&#xff1a…

淘宝商品数据库设计的一些经验

前言这几个月都在做一个通过淘宝API线下管理淘宝店的系统&#xff0c;学习了很多东西&#xff0c;这里想对淘宝商品表设计用自己的想法表现出来&#xff0c;如果你觉得很扯淡&#xff0c;可以写下自己的看法.OK&#xff0c;切入正题.淘宝的商品这块的复杂程度&#xff0c;是我见…

AT2645 [ARC076D] Exhausted?(Hall定理推论/线段树+扫描线)

AT2645 [ARC076D] Exhausted? 对于一个二分图左边点连接的是右边点的一个前缀和一个后缀&#xff0c;求解最大匹配。 首先不能直接求解最大匹配&#xff0c;但是我们可以利用Hall定理的推论求解 ∣U∣−max(∣X∣−N(∣X∣))|U|-max(|X|-N(|X|))∣U∣−max(∣X∣−N(∣X∣))…

2019-03-11-算法-进化(搜索二维矩阵II)

题目描述 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列每列的元素从上到下升序排列 示例: 现有矩阵 matrix 如下&#xff1a; [[1, 4, 7, 11, 15],[2, 5, 8, 12, 19],[3, 6, 9…

A and B and Lecture Rooms

A and B and Lecture Rooms 题意要求我们找有多少个点iii满足dis(i,x),dis(i,y)dis(i, x), dis(i, y)dis(i,x),dis(i,y)&#xff0c;输出点iii的数量即可。 首先特判无解的情况就是dis(x,y)dis(x, y)dis(x,y)为奇数时&#xff0c;接下来我们讨论有解的情况&#xff0c;大致分…