public void Load(ref object instance, IDataRecord record, MappingContext context) { for (int i = 0; i < this.Properties.Count; i++) { Node childNode = this.Properties[i]; if (!childNode.IsComplex || childNode.HasConstructorParameters) { childNode.Read(ref instance, record, context); continue; } object currentValue = childNode.Get(ref instance); if (currentValue != null) { childNode.Load(ref currentValue, record, context); } else { childNode.Read(ref instance, record, context); } } if (this.HasCollections) { if (context.SingleResult) { // if the query is expected to return a single result at most // we close the data reader to allow for collections to be loaded // using the same connection (for providers that do not support MARS) IDataReader reader = record as IDataReader; reader?.Close(); } for (int i = 0; i < this.Collections.Count; i++) { CollectionNode collectionNode = this.Collections[i]; collectionNode.Load(ref instance, context); } } }
void ReadMapping(IDataRecord record, MapGroup[] groups, MapGroup currentGroup, Node instance) { var constructorParameters = new Dictionary <MapParam, Node>(); foreach (var pair in currentGroup.Properties) { Node property = CreateSimpleProperty(instance, pair.Value, pair.Key); if (property != null) { property.Container = instance; instance.Properties.Add(property); continue; } uint valueAsNumber; if (UInt32.TryParse(pair.Value, out valueAsNumber)) { constructorParameters.Add(new MapParam(valueAsNumber, pair.Key), null); } else { this.Log?.WriteLine("-- WARNING: Couldn't find property '{0}' on type '{1}'. Ignoring column.", pair.Value, instance.TypeName); } } MapGroup[] nextLevels = (from m in groups where m.Depth == currentGroup.Depth + 1 && m.Parent == currentGroup.Name select m).ToArray(); for (int i = 0; i < nextLevels.Length; i++) { MapGroup nextLevel = nextLevels[i]; Node property = CreateComplexProperty(instance, nextLevel.Name); if (property != null) { property.Container = instance; ReadMapping(record, groups, nextLevel, property); instance.Properties.Add(property); continue; } uint valueAsNumber; if (UInt32.TryParse(nextLevel.Name, out valueAsNumber)) { constructorParameters.Add(new MapParam(valueAsNumber, nextLevel), null); } else { this.Log?.WriteLine("-- WARNING: Couldn't find property '{0}' on type '{1}'. Ignoring column(s).", nextLevel.Name, instance.TypeName); } } if (constructorParameters.Count > 0) { instance.Constructor = GetConstructor(instance, constructorParameters.Count); ParameterInfo[] parameters = instance.Constructor.GetParameters(); int i = 0; foreach (var pair in constructorParameters.OrderBy(p => p.Key.ParameterIndex)) { ParameterInfo param = parameters[i]; Node paramNode; if (pair.Key.ColumnOrdinal.HasValue) { paramNode = CreateParameterNode(pair.Key.ColumnOrdinal.Value, param); } else { paramNode = CreateParameterNode(param); ReadMapping(record, groups, pair.Key.Group, paramNode); } if (instance.ConstructorParameters.ContainsKey(pair.Key.ParameterIndex)) { var message = new StringBuilder(); message.AppendFormat(CultureInfo.InvariantCulture, "Already specified an argument for parameter '{0}'", param.Name); if (pair.Key.ColumnOrdinal.HasValue) { message.AppendFormat(CultureInfo.InvariantCulture, " ('{0}')", record.GetName(pair.Key.ColumnOrdinal.Value)); } message.Append("."); throw new InvalidOperationException(message.ToString()); } instance.ConstructorParameters.Add(pair.Key.ParameterIndex, paramNode); i++; } } if (instance.IsComplex && this.ManyIncludes != null) { var includes = this.ManyIncludes .Where(p => p.Key.Length == currentGroup.Depth + 1) .Where(p => { if (instance.Container == null) { // root node return(true); } string[] reversedBasePath = p.Key.Take(p.Key.Length - 1).Reverse().ToArray(); Node container = instance; for (int i = 0; i < reversedBasePath.Length; i++) { if (container.PropertyName != reversedBasePath[i]) { return(false); } container = container.Container; } return(true); }) .ToArray(); for (int i = 0; i < includes.Length; i++) { var pair = includes[i]; string name = pair.Key[pair.Key.Length - 1]; CollectionNode collection = CreateCollectionNode(instance, name); if (collection != null) { instance.Collections.Add(collection); if (this.manyLoaders == null) { this.manyLoaders = new Dictionary <CollectionNode, CollectionLoader>(); } this.manyLoaders.Add(collection, pair.Value); } } } }