[DataContract(Namespace = "Adhesive.Mongodb")]
public class MongodbDatabaseDescription
{
[DataMember]
public bool SentToServer { get; set; }
[DataMember]
public string TypeFullName { get; set; }
[DataMember]
public string DatabasePrefix { get; set; }
[DataMember]
public string CategoryName { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string DisplayName { get; set; }
[DataMember]
public int ExpireDays { get; set; }
[DataMember]
public List MongodbColumnDescriptionList { get; set; }
[DataMember]
public List MongodbEnumColumnDescriptionList { get; set; }
}
在这里可以看到,我们主要解析的是MongodbPersistenceEntityAttribute,对于下一级的MongodbColumnDescriptionList ,我们主要是解析每一个列的元数据,而MongodbEnumColumnDescriptionList则提取所有枚举的信息。MongodbColumnDescription的定义如下:
[DataContract(Namespace = "Adhesive.Mongodb")]
public class MongodbColumnDescription
{
[DataMember]
public string Name { get; set; }
[DataMember]
public string TypeName { get; set; }
[DataMember]
public bool IsArrayColumn { get; set; }
[DataMember]
public bool IsEntityColumn { get; set; }
[DataMember]
public string ColumnName { get; set; }
[DataMember]
public string DisplayName { get; set; }
[DataMember]
public string Description { get; set; }
[DataMember]
public bool ShowInTableView { get; set; }
[DataMember]
public bool IsTableColumn { get; set; }
[DataMember]
public bool IsTimeColumn { get; set; }
[DataMember]
public bool IsContextIdentityColumn { get; set; }
[DataMember]
public bool IsPrimaryKey { get; set; }
[DataMember]
public MongodbIndexOption MongodbIndexOption { get; set; }
[DataMember]
public MongodbFilterOption MongodbFilterOption { get; set; }
[DataMember]
public MongodbCascadeFilterOption MongodbCascadeFilterOption { get; set; }
[DataMember]
public MongodbSortOption MongodbSortOption { get; set; }
}
这里很多数据都来自MongodbPersistenceItemAttribute和MongodbPresentationItemAttribute。再来看看MongodbEnumColumnDescription:
[DataContract(Namespace = "Adhesive.Mongodb")]
public class MongodbEnumColumnDescription
{
[DataMember]
public string Name { get; set; }
[DataMember]
public Dictionary EnumItems { get; set; }
}
它就简单了,只是保存枚举的列名,和枚举每一项的数据。其实这些元数据提取本身没什么复杂的,可以想到是反射提取,并且其中还涉及到递归,需要深入每一个自定义类型,GetMongodbColumnDescription方法其中有一段这样的代码实现了递归:
if (!type.Assembly.GlobalAssemblyCache && type != pi.DeclaringType)
{
columnDescription.IsEntityColumn = true;
var properties = GetPropertyListFromCache(type);
if (properties != null)
{
foreach (var property in properties)
{
GetMongodbColumnDescription(typeFullName, fullName, columnDescriptionList, enumColumnDescriptionList, property);
}
}
}
在提取元数据的时候,另一个重要的工作是缓存一些关键的PropertyInfo的配置,以便后期处理数据的时候使用:
internal class ProperyInfoConfig
{
public bool IsCascadeFilterLevelOne { get; set; }
public bool IsCascadeFilterLevelTwo { get; set; }
public bool IsCascadeFilterLevelThree { get; set; }
public bool IsDateColumn { get; set; }
public bool IsTableName { get; set; }
public bool IsIgnore { get; set; }
public string ColumnName { get; set; }
}
因为我们在提交数据之前,需要针对级联下拉的数据进行处理,把第二级的值设置为第一级的值加上第二级的值,第三级的值设置为一加二加三,这样在筛选的时候就会很方便;此外还需要替换列名,计算表名等等,只有缓存了PropertyInfo才能无需重新读取元数据:
private static Dictionary propertyConfigCache = new Dictionary();
之前说了元数据提取部分时的逻辑,然后来看一下格式化数据时的逻辑,之前为内存队列服务的提交数据的委托挂载的方法主要实现如下: