/// <summary> /// Creates the list of property setters for a reader. /// </summary> /// <param name="type">The type of object to map to.</param> /// <param name="reader">The reader to read.</param> /// <param name="command">The command that is currently being mapped.</param> /// <param name="parameters">The list of parameters used in the mapping operation.</param> /// <param name="structure">The structure of the record being read.</param> /// <param name="startColumn">The index of the first column to map.</param> /// <param name="columnCount">The number of columns to map.</param> /// <param name="uniqueMatches">True to only return the first match per field, false to return all matches per field.</param> /// <returns>An array of setters.</returns> internal ColumnMappingEventArgs[] CreateMapping( Type type, IDataReader reader, IDbCommand command, IList <IDataParameter> parameters, IRecordStructure structure, int startColumn, int columnCount, bool uniqueMatches) { ColumnMappingEventArgs[] mapping = new ColumnMappingEventArgs[columnCount]; // convert the list of names into a list of set reflections // clone the methods list, since we are only going to use each setter once (i.e. if you return two ID columns, we will only use the first one) // Also, we want to do a case-insensitive lookup of the property, so convert the dictionary to an uppercase dictionary var setMethods = new Dictionary <string, ClassPropInfo>(ClassPropInfo.GetMappingForType(type), StringComparer.OrdinalIgnoreCase); List <IDataParameter> readOnlyParameters = null; if (parameters != null) { readOnlyParameters = new List <IDataParameter>(parameters.OfType <IDataParameter>().ToList()); } // find all of the mappings for (int i = 0; i < columnCount; i++) { // generate an event var e = new ColumnMappingEventArgs() { TargetType = type, Reader = reader, FieldIndex = i + startColumn, Parameters = readOnlyParameters, }; if (command != null) { e.CommandText = command.CommandText; e.CommandType = command.CommandType; } if (reader != null) { e.ColumnName = reader.GetSchemaTable().Rows[e.FieldIndex]["ColumnName"].ToString(); } lock (_lock) { _mappings(null, e); } // if no mapping was returned, then skip the column if (e.Canceled || String.IsNullOrEmpty(e.TargetFieldName.Trim())) { continue; } // if a column mapping override was specified, then attempt an override if (structure != null) { structure.MapColumn(e); } // get the target property based on the result string targetFieldName = e.TargetFieldName; // first see if there is a wildcard column, if not, then look up the field name ClassPropInfo setter; if (setMethods.TryGetValue("*", out setter) || setMethods.TryGetValue(targetFieldName, out setter)) { mapping[i] = e; e.ClassPropInfo = setter; InitializeMappingSerializer(e, reader, command, parameters, i); // remove the name from the list so we can only use it once if (uniqueMatches) { setMethods.Remove(setter.ColumnName); } } } return(mapping); }