/// <summary> /// Builds a <see cref="ResultPropertyCollection"/> for an <see cref="AutoResultMap"/>. /// </summary> /// <param name="dataExchangeFactory">The data exchange factory.</param> /// <param name="reader">The reader.</param> /// <param name="resultObject">The result object.</param> public static ResultPropertyCollection Build(DataExchangeFactory dataExchangeFactory, IDataReader reader, ref object resultObject) { Type targetType = resultObject.GetType(); ResultPropertyCollection properties = new ResultPropertyCollection(); try { // Get all PropertyInfo from the resultObject properties ReflectionInfo reflectionInfo = ReflectionInfo.GetInstance(targetType); string[] membersName = reflectionInfo.GetWriteableMemberNames(); IDictionary<string, ISetAccessor> propertyMap = new Dictionary<string, ISetAccessor>(); int length = membersName.Length; for (int i = 0; i < length; i++) { ISetAccessorFactory setAccessorFactory = dataExchangeFactory.AccessorFactory.SetAccessorFactory; ISetAccessor setAccessor = setAccessorFactory.CreateSetAccessor(targetType, membersName[i]); propertyMap.Add(membersName[i], setAccessor); } // Get all column Name from the reader // and build a resultMap from with the help of the PropertyInfo[]. DataTable dataColumn = reader.GetSchemaTable(); int count = dataColumn.Rows.Count; for (int i = 0; i < count; i++) { string propertyName = string.Empty; string columnName = dataColumn.Rows[i][0].ToString(); ISetAccessor matchedSetAccessor = null; propertyMap.TryGetValue(columnName, out matchedSetAccessor); int columnIndex = i; if (resultObject is Hashtable) { propertyName = columnName; ResultProperty property = new ResultProperty( propertyName, columnName, columnIndex, string.Empty, string.Empty, string.Empty, false, string.Empty, null, string.Empty, targetType, dataExchangeFactory, null); properties.Add(property); } Type propertyType = null; if (matchedSetAccessor == null) { try { propertyType = ObjectProbe.GetMemberTypeForSetter(resultObject, columnName); } catch { _logger.Error("The column [" + columnName + "] could not be auto mapped to a property on [" + resultObject + "]"); } } else { propertyType = matchedSetAccessor.MemberType; } if (propertyType != null || matchedSetAccessor != null) { propertyName = (matchedSetAccessor != null ? matchedSetAccessor.Name : columnName); ITypeHandler typeHandler = null; if (matchedSetAccessor != null) { //property.Initialize(dataExchangeFactory.TypeHandlerFactory, matchedSetAccessor); typeHandler = dataExchangeFactory.TypeHandlerFactory.GetTypeHandler(matchedSetAccessor.MemberType); } else { typeHandler = dataExchangeFactory.TypeHandlerFactory.GetTypeHandler(propertyType); } //property.PropertyStrategy = PropertyStrategyFactory.Get(property); ResultProperty property = new ResultProperty( propertyName, columnName, columnIndex, string.Empty, string.Empty, string.Empty, false, string.Empty, null, string.Empty, targetType, dataExchangeFactory, typeHandler); properties.Add(property); } } } catch (Exception e) { throw new DataMapperException("Error automapping columns. Cause: " + e.Message, e); } return properties; }
/// <summary> /// Builds the result properties. /// </summary> /// <param name="resultMapId">The result map id.</param> /// <param name="resultMapConfig">The result map config.</param> /// <param name="resultClass">The result class.</param> /// <param name="prefix">The prefix.</param> /// <param name="suffix">The suffix.</param> /// <param name="dataExchangeFactory">The data exchange factory.</param> /// <param name="waitResultPropertyResolution">The wait result property resolution.</param> /// <returns></returns> private static ResultPropertyCollection BuildResultProperties( string resultMapId, IConfiguration resultMapConfig, Type resultClass, string prefix, string suffix, DataExchangeFactory dataExchangeFactory, WaitResultPropertyResolution waitResultPropertyResolution) { ResultPropertyCollection properties = new ResultPropertyCollection(); //获取result节点的集合配置信息 ConfigurationCollection resultsConfig = resultMapConfig.Children.Find(ConfigConstants.ELEMENT_RESULT); for (int i = 0; i < resultsConfig.Count; i++) { ResultProperty mapping = null; try { mapping = ResultPropertyDeSerializer.Deserialize(resultsConfig[i], resultClass, prefix, suffix, dataExchangeFactory); } catch(Exception e) { throw new ConfigurationException("In ResultMap (" + resultMapId + ") can't build the result property: " + ConfigurationUtils.GetStringAttribute(resultsConfig[i].Attributes, ConfigConstants.ATTRIBUTE_PROPERTY) + ". Cause " + e.Message, e); } if (mapping.NestedResultMapName.Length > 0)//resultMapping属性如果有值 此处一般会有 { //添加到DefaultModelBuilder中的ResultPropertyCollection nestedProperties集合中 waitResultPropertyResolution(mapping); } properties.Add(mapping); } return properties; }
/// <summary> /// Initializes a new instance of the <see cref="ResultMap"/> class. /// </summary> /// <param name="id">Identifier used to identify the resultMap amongst the others.</param> /// <param name="className">The output class name of the resultMap.</param> /// <param name="extendMap">The extend result map bame.</param> /// <param name="groupBy">The groupBy properties</param> /// <param name="keyColumns">The key columns.</param> /// <param name="type">The result type.</param> /// <param name="dataExchange">The data exchange.</param> /// <param name="objectFactory">The object factory.</param> /// <param name="typeHandlerFactory">The type handler factory.</param> /// <param name="properties">The properties.</param> /// <param name="parameters">The parameters.</param> /// <param name="discriminator">The discriminator.</param> public ResultMap( string id, string className, string extendMap, string groupBy, string keyColumns, Type type, IDataExchange dataExchange, IFactory objectFactory, TypeHandlerFactory typeHandlerFactory, ResultPropertyCollection properties, ArgumentPropertyCollection parameters, Discriminator discriminator) { Contract.Require.That(id, Is.Not.Null & Is.Not.Empty).When("retrieving argument id in ResultMap constructor"); Contract.Require.That(className, Is.Not.Null & Is.Not.Empty).When("retrieving argument className in ResultMap constructor"); Contract.Require.That(type, Is.Not.Null).When("retrieving argument type in ResultMap constructor"); Contract.Require.That(typeHandlerFactory, Is.Not.Null).When("retrieving argument typeHandlerFactory in ResultMap constructor"); nullResultMap = new NullResultMap(); this.id = id; this.className = className; this.extendMap = extendMap; this.type = type; this.dataExchange = dataExchange; this.properties = properties; this.parameters = parameters; this.discriminator = discriminator; this.objectFactory = objectFactory; isSimpleType = typeHandlerFactory.IsSimpleType(type); if (!string.IsNullOrEmpty(groupBy)) { string[] props = groupBy.Split(','); for (int i = 0; i < props.Length; i++) { string memberName = props[i].Trim(); groupByPropertyNames.Add(memberName); } InitializeGroupByProperties(); CheckGroupBy(); } if (!string.IsNullOrEmpty(keyColumns)) { string[] columns = keyColumns.Split(','); for (int i = 0; i < columns.Length; i++) { string column = columns[i].Trim(); keyPropertyNames.Add(column); } InitializeKeysProperties(); CheckKeysProperties(); } }