在一个特殊应用中, 我们需要将内存中的一个对象持久化, 而这个对象是来自一个模板类实例化出来的, 不能保存到数据库中, 数据库中只存有此对象的模板.
由于使用到泛型的Dictionary, 而XmlSerializer却不支持默认的泛型的Dictionary, 为此我找了些资料, 并在此文中以三种不同的方式实现. 本文中约定:
方案1: 不序列化泛型的Dictionary
方案2: 定义支持泛型的Dictionary
方案3: 让每个类实现IXmlSerializable接口
本文内容:
1. 类图及类之间的关联
2. 方案1: 不序列化泛型的Dictionary
3. 方案2: 定义支持泛型的Dictionary
4. 方案3: 让每个类实现IXmlSerializable接口
5. 总结
1. 类图及类之间的关联
薪酬模板PayTemplate, 它通过Dictionary<int, PayItemTemplate>维持着多个薪酬栏目模板PayItemTemplate.
而一个PayItemTemplate通过Dictionary<int, PayItemTemplate>记录着那些使用过它的PayItemTemplate.
所以, PayTemplate与PayItemTemplate是一对多关联; PayItemTemplate是一对多的自关联.
方案1,2,3中的类关联都相似, 这里就不重复了. 详细差别可在本文末尾下载源代码查看.
2. 方案1: 不序列化泛型的Dictionary
既然知道了泛型的Dictionary不被XmlSerializer支持, 我们就避免泛型的Dictionary被序列化, 只需要在字段上加上XmlIgnore属性即可.代码如下:
46 [XmlIgnore] //带有XmlIgnore, 表示序列化时不序列化此属性
47 public Dictionary<int, PayItemTemplate> PayItemTemplateDic
48 {
49 get { return payItemTemplates; }
50 set { payItemTemplates = value; }
51 }
好了, 既然让泛型的Dictionary不被序列化了, 而我们的需求中又需要将泛型的Dictionary中的对象序列化到Xml中保存, 那怎么办呢?这里的办法就是加多一个额外的PayItemTemplate[]数组字段, 代码实现如下:
53 /// <summary>
54 /// 用于序列化PayItemTemplate集合
55 /// </summary>
56 public PayItemTemplate[] PayItemTemplates
57 {
58 get
59 {
60 List<PayItemTemplate> list = new List<PayItemTemplate>(payItemTemplates.Count);
61 foreach (KeyValuePair<int,PayItemTemplate> pit in payItemTemplates)
62 {
63 list.Add(pit.Value);
64 }
65
66 return list.ToArray();
67 }
68 set
69 {
70 payItemTemplates = new Dictionary<int, PayItemTemplate>();
71 foreach (PayItemTemplate pit in value)
72 {
73 payItemTemplates.Add(pit.Id, pit);
74 }
75 }
76 }
这就是我们需要做的, 下面进行测试, 具体的单元测试, 可在下载源代码中查看.
测试结果:
正向序列化:
<?xml version="1.0" encoding="utf-8"?>
<PayTemplate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Id>100</Id>
<Name>薪酬模版Test</Name>
<StartDate>2007-08-16T19:10:43.640625+08:00</StartDate>
<PayItemTemplates>
<PayItemTemplate>
<numbericalCategory