Ejemplo n.º 1
0
        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);
                }
            }
        }
Ejemplo n.º 2
0
        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);
                    }
                }
            }
        }