Ejemplo n.º 1
0
        /// <summary>
        ///     Resolves the alias.
        /// </summary>
        /// <param name="id">The identifier.</param>
        /// <returns></returns>
        private EntityAlias ResolveAlias(Guid id, bool reverseAlias)
        {
            EntityAlias entityAlias;
            var         key = new Tuple <Guid, bool>(id, reverseAlias);

            if (_upgradeIdToAliasMap.TryGetValue(key, out entityAlias))
            {
                return(entityAlias);
            }

            if (reverseAlias)
            {
                if (PackageData.Metadata.RelationshipTypeCallback == null)
                {
                    return(null);
                }
                RelationshipTypeEntry relType = PackageData.Metadata.RelationshipTypeCallback(id);
                if (relType?.ReverseAlias == null)
                {
                    return(null);
                }
                entityAlias = new EntityAlias(relType.ReverseAlias);
            }
            else
            {
                entityAlias = NameResolver?.Resolve(id);
            }

            _upgradeIdToAliasMap[key] = entityAlias;

            return(entityAlias);
        }
Ejemplo n.º 2
0
        /// <summary>
        ///     Handle case if one entity is a component of the other.
        /// </summary>
        /// <param name="relType">The relationship type.</param>
        /// <param name="fromEntity">The 'from' entity.</param>
        /// <param name="toEntity">The 'to' entity.</param>
        /// <returns></returns>
        private bool HandleContainedEntities(RelationshipEntry rel, RelationshipTypeEntry relType, EntityHierarchyEntry fromEntity, EntityHierarchyEntry toEntity)
        {
            if (relType == null)
            {
                return(false);
            }

            // Explicitly do not next certain relationships
            if (rel.TypeId == Guids.InSolution || rel.TypeId == Guids.IndirectInSolution)
            {
                return(false);
            }

            // if 'fwdComponent' then parent = FromId
            // if 'revComponent' then parent = ToId
            // "Clone action" is the best proxy to determine if something is a subcomponent, while still handling 'custom' reltypes.
            bool fwdComponent = relType.CloneAction == CloneActionEnum_Enumeration.CloneEntities;
            bool revComponent = !fwdComponent && relType.ReverseCloneAction == CloneActionEnum_Enumeration.CloneEntities;

            EntityHierarchyEntry parent = null;
            EntityHierarchyEntry child  = null;

            if (fwdComponent)
            {
                parent = fromEntity;
                child  = toEntity;
            }
            else if (revComponent)
            {
                parent = toEntity;
                child  = fromEntity;
            }
            else
            {
                return(false);
            }

            if (child.ParentEntity != null)
            {
                return(false);   // child already assigned to a different parent
            }
            if (WouldCauseCycle(parent, child))
            {
                return(false);
            }

            if (parent.Children == null)
            {
                parent.Children = new List <EntityHierarchyEntry>( );
            }
            parent.Children.Add(child);
            child.ParentEntity           = parent;
            child.RelationshipFromParent = rel;
            child.Direction = revComponent ? Direction.Reverse : Direction.Forward;
            return(true);
        }
Ejemplo n.º 3
0
        /// <summary>
        ///     Call database proc to gather relationship metadata from whichever package has the highest version number.
        /// </summary>
        /// <param name="uniqueTypes"></param>
        /// <returns></returns>
        private IDictionary <Guid, RelationshipTypeEntry> GetEntriesFromAppLibrary(IEnumerable <Guid> uniqueRelTypes)
        {
            Dictionary <Guid, RelationshipTypeEntry> results = new Dictionary <Guid, RelationshipTypeEntry>( );

            using (IDatabaseContext ctx = DatabaseContext.GetContext( ))
                using (IDbCommand command = ctx.CreateCommand( ))
                {
                    command.CommandType = CommandType.StoredProcedure;
                    command.CommandText = "spGetRelationshipMetadataFromAppLibraryLatest";

                    command.AddListParameter("@relTypeIds", TableValuedParameterType.Guid, uniqueRelTypes.Select(g => (object)g));

                    using (IDataReader reader = command.ExecuteReader( ))
                    {
                        int relTypeIdCol          = reader.GetOrdinal("RelTypeId");
                        int aliasCol              = reader.GetOrdinal("alias");
                        int reverseAliasCol       = reader.GetOrdinal("reverseAlias");
                        int cardinalityCol        = reader.GetOrdinal("cardinality");
                        int cloneActionCol        = reader.GetOrdinal("cloneAction");
                        int reverseCloneActionCol = reader.GetOrdinal("reverseCloneAction");

                        while (reader.Read( ))
                        {
                            Guid relTypeId = reader.GetGuid(relTypeIdCol);

                            var relTypeEntry = new RelationshipTypeEntry
                            {
                                TypeId             = relTypeId,
                                Alias              = reader.IsDBNull(aliasCol) ? null : reader.GetString(aliasCol),
                                ReverseAlias       = reader.IsDBNull(reverseAliasCol) ? null : reader.GetString(reverseAliasCol),
                                CloneAction        = DecodeCloneAction(reader, cloneActionCol),
                                ReverseCloneAction = DecodeCloneAction(reader, reverseCloneActionCol),
                            };

                            results.Add(relTypeId, relTypeEntry);
                        }
                    }
                }
            return(results);
        }
Ejemplo n.º 4
0
        public EntityHierarchyEntry BuildEntityHierarchy([NotNull] PackageData packageData)
        {
            if (packageData == null)
            {
                throw new ArgumentNullException(nameof(packageData));
            }

            _root = new EntityHierarchyEntry
            {
                Children             = new List <EntityHierarchyEntry>( ),
                ForwardRelationships = new List <RelationshipEntry>( )
            };

            // Create dictionary of entity nodes
            if (packageData.Entities != null)
            {
                _entities = packageData.Entities.ToDictionary(
                    e => e.EntityId, e => new EntityHierarchyEntry {
                    Entity = e
                });
            }
            else
            {
                _entities = new Dictionary <Guid, EntityHierarchyEntry>( );
            }


            // Walk all relationships
            // Note: relationships get canonically ordered to ensure deterministic construction of hierarchy
            foreach (RelationshipEntry rel in packageData.Relationships.OrderBy(r => r.TypeId).ThenBy(r => r.FromId).ThenBy(r => r.ToId))
            {
                EntityHierarchyEntry fromEntity;
                EntityHierarchyEntry toEntity;
                _entities.TryGetValue(rel.FromId, out fromEntity);
                _entities.TryGetValue(rel.ToId, out toEntity);

                // Handle 'type' relationship
                if (fromEntity != null && rel.TypeId == Guids.IsOfType && fromEntity.TypeRelationship == null)
                {
                    fromEntity.TypeRelationship = rel;
                    continue;
                }

                RelationshipTypeEntry relType = GetRelationshipMetadata(rel.TypeId);

                // Detect entities that contain entities
                if (fromEntity != null && toEntity != null)
                {
                    if (HandleContainedEntities(rel, relType, fromEntity, toEntity))
                    {
                        continue;
                    }
                }

                // Other relationships - find somewhere to add them.
                if (fromEntity != null)
                {
                    if (fromEntity.ForwardRelationships == null)
                    {
                        fromEntity.ForwardRelationships = new List <RelationshipEntry>( );
                    }
                    fromEntity.ForwardRelationships.Add(rel);
                    continue;
                }

                if (toEntity != null)
                {
                    if (toEntity.ReverseRelationships == null)
                    {
                        toEntity.ReverseRelationships = new List <RelationshipEntry>( );
                    }
                    toEntity.ReverseRelationships.Add(rel);
                    continue;
                }

                // Nowhere else to add them..
                _root.ForwardRelationships.Add(rel);
            }

            // Gather top tier entities into root entity
            foreach (var entity in _entities.Values)
            {
                if (entity.ParentEntity != null)
                {
                    continue;
                }
                _root.Children.Add(entity);
                entity.ParentEntity = _root;
            }

            return(_root);
        }