通过映射实体字段属性快速生成目标格式数据
在报文通信协议或者数据转换迁移这类应用中,不知您是如何组装报文,如何关联新老数据库字段的。因为之前我实施过这两类应用,在实施过程中逐渐萃取出了一个简单实用的类库(其实只是很简单的几个类,可以点此下载该类库,可以自己使用和商用,但请发email告知。),通过这个类库可以很便捷地进行通信报文的组装,新老数据库字段的映射,从而高效的完成目标功能。
该类库主要有四个类:MappingFieldAttribute、MappingField、MappingFieldException和MappingData。如下:
这里不再继续讨论类库设计什么其他的,这里面其实没多少值得称道的。这个类库本身存在的价值就在于让大家更简单更实用的完成报文组装、数据字段映射等工作,所以我尽量说下怎么快速使用这个类库。
对于报文或数据表,一般我们都有一个业务实体类与之对应。该实体类里的每一个成员字段或属性可以对应零个、一个或多个的业务字段,此时这种对应关系正是通过 MappingFieldAttribute特性标签来标识的。MappingFieldAttribute允许被多次使用在某个成员字段或属性上,同时被标识的属性可以由派生类和重写成员继承(也就是说可以搜索出父类和子类所有标有MappingFieldAttribute的字段属性出来,这点也很实用)。同时,所有使用这个类库的业务实体类都继承自MappingData类,这样才能自动拥有获取对映射字段的相关操作方法。
DemoPackage实体类中CustomerID属性及其映射规则:
/**//// <summary>
/// 客户编号。
/// </summary>
[MappingField("客户号", 20, false, 2)]
public string CustomerID
...{
get ...{ return _customerId; }
set ...{ _customerId = value; }
}
![]()
/**//// <summary>
/// 证件类型。A 为身份证,B 为护照,C 为军官证,0 为其他。
/// </summary>
[MappingField("证件类型", 1, false, new string[]...{"A", "B", "C", "0"}, 6)]
public string CreditType
...{
get ...{ return _creditType; }
set ...{ _creditType = value; }
}
可以看到MappingFieldAttribute有几个属性,分别为:
# 映射字段名称
# 是否必填
# 最小长度
# 最大长度
# 允许取值范围或集合
# 排序索引号
这些数据格式规则是从大部分映射关系中抽取出来的特征,这些特征都是具体某个映射字段所具备的基本特征。你可以通过这些特征严格控制映射字段的映射规则,保证不仅能够正常映射,同时能够准确映射。可以通过MappingData.EnsureValidation()或MappingField.Validate()对映射字段进行规则校验。
下面分别为快速输出目标Xml格式、报文格式和正常格式的代码:
/**//// <summary>
/// 输出 Xml 字符串。
/// </summary>
public virtual string ToXml()
...{
StringBuilder builder = new StringBuilder();
![]()
// 因为一般 Xml 的节点不需要排序,所以使用 GetMappingFields() 获取所有
// 标有 MappingFieldAttribute 特性标签的字段
Hashtable fieldTable = this.GetMappingFields();
![]()
builder.Append("<RequestParameter>");
![]()
foreach (DictionaryEntry entry in fieldTable)
...{
MappingField field = entry.Value as MappingField;
field.Validate();
![]()
string node = Utility.CreateXmlNode(field.FieldName, field.Value.ToString());
builder.Append(node);
}
![]()
builder.Append("</RequestParameter>");
![]()
string xml = Utility.InitializeXmlPackage(builder.ToString());
return xml;
}
/**//// <summary>
/// 输出通信报文。此处报文为固定长度的报文,不足长度需进行补足长度处理。
/// </summary>
public virtual string ToDatagram()
...{
StringBuilder builder = new StringBuilder();
ArrayList fieldArray = this.GetMappingFieldArray();
![]()
for (int i = 0; i < fieldArray.Count; i++)
...{
MappingField field = fieldArray[i] as MappingField;
field.Validate();
![]()
string node = string.Empty;
![]()
if (field.MemberType == typeof(int))
...{
// 如果是 int 类型,则在前面补 0,以达到规定的长度。
node = field.Value.ToString().PadLeft(field.Attribute.MaxLength, '0');
}
else
...{
// 如果不是 int 类型,比如 string 类型,则在后面补空格,以达到规定的长度。
node = field.Value.ToString().PadRight(field.Attribute.MaxLength, ' ');
}
![]()
builder.Append(node);
}
![]()
return builder.ToString();
}
可以看到,当实体字段越多时,利用本方案进行映射组装目标内容是非常便捷实用的。对于在数据转换迁移中,最典型的应用场景要算纵表结构导成横表结构。通过针对横表结构建立一个实体类,每个类成员字段属性都加一个或多个MappingFieldAttribute与纵表结构中的字段名称建立映射关联关系,最后就可以很方便利用这类库把数据从纵表中一一对应到新数据实体(对应横表结构)中,最后导入目标数据库。
当然,获取你还可以找到其他应用场景,相信你可以通过自定义扩充该类库而方便快速的实现你所要的功能。最后,记得给我发一份你的成果。J
posted on 2006-07-10 20:02:00 by liuhuimiao 评论(11) 阅读(5919)






}