/// <summary> /// 解析一条数据 /// </summary> private T ReadOneItem <T>(IDataReader dr, ClassDesc clsDesc, IDbAccessorFactory dbAcsFty, object key) where T : class, new() { while (dr.Read()) { return(CreateOneItem(typeof(T), dr, clsDesc, dbAcsFty, key) as T); } return(null); }
/// <summary> /// 从已加载的数据中获取对应类型的List<>, 如果对应类型不存在, 加载并返回加载后的结果 /// </summary> private IList GetSubItemList(Type type, IDbAccessorFactory dbAcsFty, object key) { ClassDesc clsDesc = GetClassDesc(type); IDbAccessor dbAccessor = dbAcsFty.GetDbAccessor(clsDesc.TableName); IDataReader reader = dbAccessor.Query(GetQueryString(clsDesc.TableName, clsDesc.RootKeyAttribute.ColumnName, key)); IList list = ReadItems(type, reader, clsDesc, dbAcsFty, key); dbAccessor.CloseDbReader(); return(list); }
/// <summary> /// 解析所有数据 /// </summary> private IList ReadItems(Type type, IDataReader dr, ClassDesc clsDesc, IDbAccessorFactory dbAcsFty, object key) { IList list = Activator.CreateInstance(typeof(List <>).MakeGenericType(type)) as IList; while (dr.Read()) { list.Add(CreateOneItem(type, dr, clsDesc, dbAcsFty, key)); } return(list); }
/// <summary> /// 解析所有数据 /// </summary> private List <T> ReadItems <T>(IDataReader dr, ClassDesc clsDesc, IDbAccessorFactory dbAcsFty, object key) where T : class, new() { List <T> list = new List <T>(); while (dr.Read()) { list.Add(CreateOneItem(typeof(T), dr, clsDesc, dbAcsFty, key) as T); } return(list); }
/// <summary> /// 判断一个外键属性值是否与它引用主键属性值一致 /// </summary> private static bool IsMatchReferenceClass(ClassDesc clsDesc, object obj, object refObj) { for (int i = 0; i < clsDesc.FkPropertyInfoList.Count; i++) { var fkPropertyDesc = clsDesc.FkPropertyInfoList[i]; if (fkPropertyDesc.propertyInfo.GetValue(obj, null).Equals(fkPropertyDesc.referencedPropertyInfo.GetValue(refObj, null)) == false) { return(false); } } return(true); }
/// <summary> /// 从数据组中将于referenceObj对应的实体填充到referenceList /// </summary> private static void AddSubItems2ReferenceList(IList list, ClassDesc clsDesc, IList refList, object refObj) { for (int i = 0; i < list.Count; i++) { var obj = list[i]; #if UNITY_IPHONE || UNITY_IOS #else if (IsMatchReferenceClass(clsDesc, obj, refObj)) #endif { refList.Add(obj); } } }
public ClassDesc GetClassDesc(Type type) { ClassDesc clsDesc = null; if (clsDescDic.TryGetValue(type, out clsDesc)) { return(clsDesc); } clsDesc = ClassDesc.CreateClassDesc(type, this); clsDescDic.Add(type, clsDesc); return(clsDesc); }
private void addNonMergeColumn(Type type, IDataReader dr, ClassDesc clsDesc, ref object model, int idx) { Debug.LogError("addNonMergeColumn method called..............."); var propertyDesc = clsDesc.GetPropertyInfo(dr.GetName(idx)); if (propertyDesc != null) { if (dr[idx] is DBNull) { Debug.Log(string.Format("DBNull found in column : {0}.If it's a test record, ignore", dr.GetName(idx))); } else if (propertyDesc.attribute.CustomType == null) { // 设置非自定义值 // bool值特殊处理 if (propertyDesc.propertyInfo.PropertyType == typeof(bool)) { propertyDesc.propertyInfo.SetValue(model, Convert.ToInt32(dr[idx]) == 1, null); } else { if (propertyDesc.propertyInfo.PropertyType == typeof(string)) { string value = dr[idx] as string; propertyDesc.propertyInfo.SetValue(model, value, null); } else { propertyDesc.propertyInfo.SetValue(model, dr[idx], null); } } } else { // 对于自定义类型值, 使用CustomDBClass转换 if (dr[idx].GetType() != typeof(string)) { Debug.LogError(string.Format("Column value of custom type must be string : {0}", dr.GetName(idx))); } else { var value = ConfigDataBase.Instance.CustomDbClass.ParseType(propertyDesc.attribute.CustomType, dr[idx] as string); propertyDesc.propertyInfo.SetValue(model, value, null); } } } }
/// <summary> /// 获取整个表中的所有数据 /// </summary> public List <T> QueryAllData <T>(IDbAccessorFactory dbAcsFty) where T : class, new() { try { ClassDesc clsDesc = GetClassDesc(typeof(T)); IDbAccessor dbAccessor = dbAcsFty.GetDbAccessor(clsDesc.TableName); IDataReader reader = dbAccessor.Query(GetQueryString(clsDesc.TableName, clsDesc.KeyAttribute.ColumnName, null)); List <T> result = ReadItems <T>(reader, clsDesc, dbAcsFty, null); dbAccessor.CloseDbReader(); return(result); } catch (Exception e) { var sb = new StringBuilder(); sb.AppendLine(e.Message); sb.AppendLine(e.StackTrace); Debug.LogError(sb.ToString()); return(new List <T>()); } }
/// <summary> /// 从数据库类创建描述类 /// </summary> /// <param name="type"></param> /// <param name="clsLoader"></param> /// <returns></returns> public static ClassDesc CreateClassDesc(Type type, DbClassLoader dbClsLoader) { ClassDesc clsDesc = new ClassDesc(); clsDesc.classType = type; if (!type.IsDefined(typeof(DbTableAttribute), false)) { // 数据库类需要定义DbTableAttribute Debug.LogError(string.Format("Missing table name {0}", type.ToString())); } else { // 获取表名 var atbAyy = type.GetCustomAttributes(typeof(DbTableAttribute), false); if (atbAyy.Length != 0) { var atb = atbAyy[0] as DbTableAttribute; clsDesc.tableName = atb.TableName; clsDesc.className = atb.ClassName; clsDesc.toClassName = atb.ToClassName; clsDesc.toNameStr = atb.ToNameStr; } } // 分析属性, 同时需要分析基类的属性 var currentType = type; while (currentType != null && currentType != typeof(object)) { CollectPropertyInfo(currentType.GetProperties(), clsDesc, dbClsLoader); currentType = currentType.BaseType; } return(clsDesc); }
private static void CollectPropertyInfo(PropertyInfo[] piArr, ClassDesc clsDesc, DbClassLoader dbClsLoader) { for (int i = 0; i < piArr.Length; i++) { PropertyInfo pi = piArr[i]; object[] atbArr = pi.GetCustomAttributes(typeof(DbColumnAttribute), false); object[] splitAtbArr = pi.GetCustomAttributes(typeof(DbSplitColumnAttribute), false); object[] splitRangeAtbArr = pi.GetCustomAttributes(typeof(DbSplitRangeAttribute), false); object[] mergeAtbArr = pi.GetCustomAttributes(typeof(DbMergeColumnAttribute), false); if (atbArr.Length != 0) { // 检测和获取主键列信息 var atb = atbArr[0] as DbColumnAttribute; if (atb.KeyColumn) { // 主键一定不是外键 if (atb.IsForeignKey) { throw new Exception("Pk can't be foreign key."); } // 只有一个主键 if (clsDesc.keyAttribute != null) { Debug.LogError(string.Format("Key column already exist {0}", atb.ColumnName)); } else { clsDesc.keyAttribute = atb; } } if (atb.IsForeignKey) { // 保存外键信息 var foreignKeyPropertyDesc = new ForeignKeyPropertyDesc(); foreignKeyPropertyDesc.attribute = atb; foreignKeyPropertyDesc.propertyInfo = pi; var refClsDesc = dbClsLoader.GetClassDesc(atb.ReferencedClass); foreignKeyPropertyDesc.referencedPropertyInfo = refClsDesc.GetPropertyInfo(atb.ReferencedColumn).propertyInfo; clsDesc.rootKeyAttribute = atb; clsDesc.fkPropertyInfoList.Add(foreignKeyPropertyDesc); } if (clsDesc.propertyInfoDic.ContainsKey(atb.ColumnName)) { Debug.LogWarning(string.Format("Duplicated column name {0}", atb.ColumnName)); } else { var propertyDesc = new PropertyDesc(); propertyDesc.attribute = atb; propertyDesc.propertyInfo = pi; clsDesc.propertyInfoDic.Add(atb.ColumnName, propertyDesc); } continue; } else if (splitAtbArr.Length != 0) { var splitAtb = splitAtbArr[0] as DbSplitColumnAttribute; if (clsDesc.splitPropertyInfoDic.ContainsKey(splitAtb.ColumnName)) { Debug.LogWarning(string.Format("Duplicated column name {0}", splitAtb.ColumnName)); } else { var propertyDesc = new SplitPropertyDesc(); propertyDesc.splitAttribute = splitAtb; propertyDesc.propertyInfo = pi; clsDesc.splitPropertyInfoDic.Add(splitAtb.ColumnName, propertyDesc); } continue; } else if (mergeAtbArr.Length != 0) { var mergeAtb = mergeAtbArr[0] as DbMergeColumnAttribute; if (clsDesc.mergePropertyInfoDic.ContainsKey(mergeAtb.FieldTypeName)) { Debug.LogWarning(string.Format("Duplicated column name {0}", mergeAtb.FieldTypeName)); } else { var propertyDesc = new MergePropertyDesc(); propertyDesc.mergeAttribute = mergeAtb; propertyDesc.propertyInfo = pi; clsDesc.mergePropertyInfoDic.Add(mergeAtb.FieldTypeName, propertyDesc); } continue; } else if (splitRangeAtbArr.Length != 0) { var splitRangeAtb = splitRangeAtbArr[0] as DbSplitRangeAttribute; if (clsDesc.splitRangePropertyInfoDic.ContainsKey(splitRangeAtb.ColumnName)) { Debug.LogWarning(string.Format("Duplicated column name {0}", splitRangeAtb.ColumnName)); } else { var propertyDesc = new SplitRangePropertyDesc(); propertyDesc.rangeAttribute = splitRangeAtb; propertyDesc.propertyInfo = pi; clsDesc.splitRangePropertyInfoDic.Add(splitRangeAtb.ColumnName, propertyDesc); } } // 获取子表信息 atbArr = pi.GetCustomAttributes(typeof(DbColumnSubTableAttribute), false); if (atbArr.Length != 0) { var atb = atbArr[0] as DbColumnSubTableAttribute; var subTablePropertyDesc = new SubTablePropertyDesc(); subTablePropertyDesc.attribute = atb; subTablePropertyDesc.propertyInfo = pi; clsDesc.subTablePropertyDescList.Add(subTablePropertyDesc); continue; } } }
/// <summary> /// 从数据流获取数据类, 支持外键 /// </summary> private object CreateOneItem(Type type, IDataReader dr, ClassDesc clsDesc, IDbAccessorFactory dbAcsFty, object key) { // 创建具体类型 var model = Activator.CreateInstance(type); object localKey = null; // 填充表数据 for (int i = 0; i < dr.FieldCount; i++) { var propertyDesc = clsDesc.GetPropertyInfo(dr.GetName(i)); if (propertyDesc != null) { if (clsDesc.KeyAttribute != null && propertyDesc.attribute.ColumnName.Equals(clsDesc.KeyAttribute.ColumnName)) { localKey = dr[i]; } if (dr[i] is DBNull) { Debug.LogWarning(string.Format("DBNull found in column : {0}.If it's test record, ignore", dr.GetName(i))); } else if (propertyDesc.attribute.CustomType == null) { if (propertyDesc.attribute.IsFloatCol) { int ori = Convert.ToInt32(dr[i]); float dst = (float)ori / 10000; propertyDesc.propertyInfo.SetValue(model, dst, null); } else { // 设置非自定义值 // bool值特殊处理 if (propertyDesc.propertyInfo.PropertyType == typeof(bool)) { propertyDesc.propertyInfo.SetValue(model, Convert.ToInt32(dr[i]) == 1, null); } else if (propertyDesc.propertyInfo.PropertyType == typeof(int)) { propertyDesc.propertyInfo.SetValue(model, Convert.ToInt32(dr[i]), null); } else { if (propertyDesc.propertyInfo.PropertyType == typeof(string)) { string value = dr[i] as string; propertyDesc.propertyInfo.SetValue(model, value, null); } else { propertyDesc.propertyInfo.SetValue(model, dr[i], null); } } } } else { // 对于自定义类型值, 使用CustomDBClass转换 if (dr[i].GetType() != typeof(string)) { Debug.LogError(string.Format("Column value of custom type must be string : {0}", dr.GetName(i))); } else { var value = ConfigDataBase.Instance.CustomDbClass.ParseType(propertyDesc.attribute.CustomType, dr[i] as string); propertyDesc.propertyInfo.SetValue(model, value, null); } } } else { var splitPropertyInfo = clsDesc.GetSplitPropertyInfo(dr.GetName(i)); var splitRangeInfo = clsDesc.GetSplitRangePropertyInfo(dr.GetName(i)); if (splitPropertyInfo != null) { if (dr[i] is DBNull || dr.GetValue(i) == null) { Debug.LogWarning(string.Format("DBNull found in column : {0}. If it's test record, ignore", dr.GetName(i))); } else { AddSplitColumn(splitPropertyInfo.splitAttribute.Type, splitPropertyInfo.propertyInfo, dr.GetValue(i).ToString(), splitPropertyInfo.splitAttribute.IsCustomType, model); } } else if (splitRangeInfo != null) { if (dr[i] is DBNull || dr.GetValue(i) == null) { Debug.LogWarning(string.Format("DBNull found in column : {0}.If it's test record, ignore", dr.GetName(i))); } else { AddSplitRangeColumn(splitRangeInfo.propertyInfo, dr.GetValue(i).ToString(), model); } } else { int dstPrefixLen = 0; string className = string.Empty; if (string.IsNullOrEmpty(clsDesc.ToClassName)) { className = clsDesc.ClassName + "List"; dstPrefixLen = clsDesc.TableName.Length;// 如此,则合并表不能有editor等类似的前缀 } else // 有to_name注释 { // 需要根据className 去 获得mergeColumnDesc className = clsDesc.ToClassName + "List"; dstPrefixLen = clsDesc.ToNameStr.Length; } var mergeColumnDesc = clsDesc.GetMergePropertyInfo(className); if (mergeColumnDesc != null) { PropertyInfo[] piArr = mergeColumnDesc.mergeAttribute.Type.GetProperties(); DbColumnAttribute secondAtb = piArr[1].GetCustomAttributes(typeof(DbColumnAttribute), false)[0] as DbColumnAttribute; string dstName = secondAtb.ColumnName; int mergeColCount = piArr.Length; string colName = dr.GetName(i); int index = colName.IndexOf('_'); if (index != -1 && dr.FieldCount >= i + mergeColCount - 1) { string prefix = colName.Substring(0, index); dstName = prefix + dstName.Substring(dstPrefixLen); if (colName.Equals(dstName, StringComparison.CurrentCultureIgnoreCase)) { List <string> valueList = new List <string>(); valueList.Add(prefix.ToUpper()); valueList.Add(i.ToString()); for (int j = 1; j < mergeColCount - 1; j++) { colName = dr.GetName(i + j); DbColumnAttribute atb = piArr[j + 1].GetCustomAttributes(typeof(DbColumnAttribute), false)[0] as DbColumnAttribute; dstName = atb.ColumnName; dstName = prefix + dstName.Substring(dstPrefixLen); if (!colName.Equals(dstName, StringComparison.CurrentCultureIgnoreCase)) { throw new InvalidOperationException("DBClassLoader found MergeTable column format error"); } else { valueList.Add((j + i).ToString()); } } AddMergeColumn(mergeColumnDesc.mergeAttribute.Type, mergeColumnDesc.propertyInfo, model, valueList, dr); i += mergeColCount - 2; } else { addNonMergeColumn(mergeColumnDesc.mergeAttribute.Type, dr, clsDesc, ref model, i); } } else { addNonMergeColumn(mergeColumnDesc.mergeAttribute.Type, dr, clsDesc, ref model, i); } } } } } // 填充子表数据 for (int i = 0; i < clsDesc.SubTablePropertyDescList.Count; i++) { var subTablePropertyDesc = clsDesc.SubTablePropertyDescList[i]; // 外键属性都应该是List<>类型 var list = subTablePropertyDesc.propertyInfo.GetValue(model, null) as IList; // 根据具List<>对应的泛型类型获取数据 var subItemList = GetSubItemList(subTablePropertyDesc.attribute.ClassType, dbAcsFty, localKey); // 将于model匹配的数据添加到对应的外键属性 AddSubItems2ReferenceList(subItemList, GetClassDesc(subTablePropertyDesc.attribute.ClassType), list, model); } return(model); }