public override object MapProperty(NodeMappingContext context)
        {
            int?id = null;

            // Get ID
            if (AllowCaching &&
                Engine.CacheProvider != null &&
                Engine.CacheProvider.ContainsPropertyValue(context.Id, DestinationInfo.Name))
            {
                id = Engine.CacheProvider.GetPropertyValue(context.Id, DestinationInfo.Name) as int?;
            }
            else
            {
                var node = context.GetNode();

                if (node == null || string.IsNullOrEmpty(node.Name))
                {
                    throw new InvalidOperationException("Node cannot be null or empty");
                }

                if (string.IsNullOrEmpty(SourcePropertyAlias))
                {
                    // Get closest parent
                    var aliases = Engine
                                  .GetCompatibleNodeTypeAliases(DestinationInfo.PropertyType)
                                  .ToArray();
                    var ancestorNode = node.Ancestors()
                                       .FirstOrDefault(x => aliases.Contains(x.DocumentTypeAlias));

                    if (ancestorNode != null)
                    {
                        // Found one
                        id = ancestorNode.Id;

                        context.AddNodeToContextCache(ancestorNode);
                    }

                    if (_mapping != null)
                    {
                        id = _mapping(context, id);
                    }
                }
                else
                {
                    if (_mapping == null)
                    {
                        // Map ID from node property
                        id = GetSourcePropertyValue <int?>(node);
                    }
                    else
                    {
                        // Custom mapping
                        id = _mapping(context, GetSourcePropertyValue(node, _sourcePropertyType));
                    }
                }

                if (AllowCaching &&
                    Engine.CacheProvider != null)
                {
                    Engine.CacheProvider.InsertPropertyValue(context.Id, DestinationInfo.Name, id);
                }
            }

            if (!id.HasValue)
            {
                // Not found
                return(null);
            }

            // Map to model
            var childPaths   = GetNextLevelPaths(context.Paths);
            var childContext = new NodeMappingContext(id.Value, childPaths, context);

            return(Engine.Map(childContext, DestinationInfo.PropertyType));
        }
        public override object MapProperty(NodeMappingContext context)
        {
            int? id = null;

            // Get ID
            if (AllowCaching
                && Engine.CacheProvider != null
                && Engine.CacheProvider.ContainsPropertyValue(context.Id, DestinationInfo.Name))
            {
                id = Engine.CacheProvider.GetPropertyValue(context.Id, DestinationInfo.Name) as int?;
            }
            else
            {
                var node = context.GetNode();

                if (node == null || string.IsNullOrEmpty(node.Name))
                {
                    throw new InvalidOperationException("Node cannot be null or empty");
                }

                if (string.IsNullOrEmpty(SourcePropertyAlias))
                {
                    // Get closest parent
                    var aliases = Engine
                        .GetCompatibleNodeTypeAliases(DestinationInfo.PropertyType)
                        .ToArray();
                    var ancestorNode = node.Ancestors()
                        .FirstOrDefault(x => aliases.Contains(x.DocumentTypeAlias));

                    if (ancestorNode != null)
                    {
                        // Found one
                        id = ancestorNode.Id;

                        context.AddNodeToContextCache(ancestorNode);
                    }

                    if (_mapping != null)
                    {
                        id = _mapping(context, id);
                    }
                }
                else
                {
                    if (_mapping == null)
                    {
                        // Map ID from node property
                        id = GetSourcePropertyValue<int?>(node);
                    }
                    else
                    {
                        // Custom mapping
                        id = _mapping(context, GetSourcePropertyValue(node, _sourcePropertyType));
                    }
                }

                if (AllowCaching
                    && Engine.CacheProvider != null)
                {
                    Engine.CacheProvider.InsertPropertyValue(context.Id, DestinationInfo.Name, id);
                }
            }

            if (!id.HasValue)
            {
                // Not found
                return null;
            }

            // Map to model
            var childPaths = GetNextLevelPaths(context.Paths);
            var childContext = new NodeMappingContext(id.Value, childPaths, context);

            return Engine.Map(childContext, DestinationInfo.PropertyType);
        }
示例#3
0
        public override object MapProperty(NodeMappingContext context)
        {
            IEnumerable <int> ids = null;

            // Get IDs
            if (AllowCaching &&
                Engine.CacheProvider != null &&
                Engine.CacheProvider.ContainsPropertyValue(context.Id, DestinationInfo.Name))
            {
                ids = Engine.CacheProvider.GetPropertyValue(context.Id, DestinationInfo.Name) as int[];
            }
            else
            {
                var node = context.GetNode();

                if (node == null || string.IsNullOrEmpty(node.Name))
                {
                    throw new InvalidOperationException("Node cannot be null or empty");
                }

                if (string.IsNullOrEmpty(SourcePropertyAlias))
                {
                    // Get compatible descendants
                    var aliases = Engine.GetCompatibleNodeTypeAliases(_elementType);

                    var nodes = aliases.SelectMany(alias => node.GetDescendantNodesByType(alias));

                    // Might as well store the nodes if we're creating them
                    foreach (var n in nodes)
                    {
                        context.AddNodeToContextCache(n);
                    }

                    ids = nodes.Select(n => n.Id);

                    if (_mapping != null)
                    {
                        ids = _mapping(context, ids);
                    }
                }
                else
                {
                    if (_mapping == null)
                    {
                        // Maps IDs from node property
                        ids = GetSourcePropertyValue <IEnumerable <int> >(node);
                    }
                    else
                    {
                        // Custom mapping
                        ids = _mapping(context, GetSourcePropertyValue(node, _sourcePropertyType));
                    }
                }
            }

            if (_elementType == typeof(int))
            {
                // Map ID collection
                return(_canAssignDirectly
                    ? ids
                    : Activator.CreateInstance(DestinationInfo.PropertyType, ids));
            }

            // Map model collection
            var childPaths       = GetNextLevelPaths(context.Paths);
            var sourceListType   = typeof(List <>).MakeGenericType(_elementType);
            var mappedCollection = Activator.CreateInstance(sourceListType);
            var missingIds       = new List <int>();

            foreach (var id in ids)
            {
                var childContext  = new NodeMappingContext(id, childPaths, context);
                var mappedElement = Engine.Map(childContext, _elementType);

                if (mappedElement == null)
                {
                    // ID does not exist
                    missingIds.Add(id);
                }
                else
                {
                    // Like "items.Add(item)" but for generic list
                    sourceListType.InvokeMember("Add", BindingFlags.InvokeMethod, null, mappedCollection, new object[] { mappedElement });
                }
            }

            if (AllowCaching &&
                Engine.CacheProvider != null)
            {
                Engine.CacheProvider.InsertPropertyValue(context.Id, DestinationInfo.Name, ids.Except(missingIds).ToArray());
            }

            return(_canAssignDirectly
                ? mappedCollection
                : Activator.CreateInstance(DestinationInfo.PropertyType, mappedCollection));
        }