Example #1
0
        private void AddModelDependencies(
            KeyToListMap <EntityKey, UpdateCommand> producedMap, KeyToListMap <EntityKey, UpdateCommand> requiredMap)
        {
            foreach (var keyAndCommands in requiredMap.KeyValuePairs)
            {
                var key = keyAndCommands.Key;
                var commandsRequiringKey = keyAndCommands.Value;

                foreach (var commandProducingKey in producedMap.EnumerateValues(key))
                {
                    foreach (var commandRequiringKey in commandsRequiringKey)
                    {
                        // command cannot depend on itself and only function commands
                        // need to worry about model dependencies (dynamic commands know about foreign keys)
                        if (!ReferenceEquals(commandProducingKey, commandRequiringKey)
                            &&
                            (commandProducingKey.Kind == UpdateCommandKind.Function ||
                             commandRequiringKey.Kind == UpdateCommandKind.Function))
                        {
                            // add a dependency
                            AddEdge(commandProducingKey, commandRequiringKey);
                        }
                    }
                }
            }
        }
        private void CollectUnreachableTypes(Set <EntityType> reachableTypes, out KeyToListMap <EntityType, LineInfo> entityTypes, out KeyToListMap <EntityType, LineInfo> isTypeOfEntityTypes)
        {
            // Collect line infos for types in violation
            entityTypes         = new KeyToListMap <EntityType, LineInfo>(EqualityComparer <EntityType> .Default);
            isTypeOfEntityTypes = new KeyToListMap <EntityType, LineInfo>(EqualityComparer <EntityType> .Default);

            if (reachableTypes.Count == this.MappedEntityTypes.Count)
            {
                // All types are reachable; nothing to check
                return;
            }

            // Find IsTypeOf mappings where no type in hierarchy can generate a row
            foreach (var isTypeOf in m_isTypeOfLineInfos.Keys)
            {
                if (!MetadataHelper.GetTypeAndSubtypesOf(isTypeOf, m_itemCollection, false)
                    .Cast <EntityType>()
                    .Intersect(reachableTypes)
                    .Any())
                {
                    // no type in the hierarchy is reachable...
                    isTypeOfEntityTypes.AddRange(isTypeOf, m_isTypeOfLineInfos.EnumerateValues(isTypeOf));
                }
            }

            // Find explicit types not generating a value
            foreach (var entityType in m_entityTypeLineInfos.Keys)
            {
                if (!reachableTypes.Contains(entityType))
                {
                    entityTypes.AddRange(entityType, m_entityTypeLineInfos.EnumerateValues(entityType));
                }
            }
        }
 private void AddForeignKeyEdges(
     KeyToListMap <UpdateCommandOrderer.ForeignKeyValue, UpdateCommand> predecessors)
 {
     foreach (DynamicUpdateCommand dynamicUpdateCommand in this.Vertices.OfType <DynamicUpdateCommand>())
     {
         if (dynamicUpdateCommand.Operator == ModificationOperator.Update || ModificationOperator.Insert == dynamicUpdateCommand.Operator)
         {
             foreach (ReferentialConstraint enumerateValue1 in this._sourceMap.EnumerateValues((EntitySetBase)dynamicUpdateCommand.Table))
             {
                 UpdateCommandOrderer.ForeignKeyValue key1;
                 UpdateCommandOrderer.ForeignKeyValue key2;
                 if (UpdateCommandOrderer.ForeignKeyValue.TryCreateSourceKey(enumerateValue1, dynamicUpdateCommand.CurrentValues, true, out key1) && (dynamicUpdateCommand.Operator != ModificationOperator.Update || !UpdateCommandOrderer.ForeignKeyValue.TryCreateSourceKey(enumerateValue1, dynamicUpdateCommand.OriginalValues, true, out key2) || !this._keyComparer.Equals(key2, key1)))
                 {
                     foreach (UpdateCommand enumerateValue2 in predecessors.EnumerateValues(key1))
                     {
                         if (enumerateValue2 != dynamicUpdateCommand)
                         {
                             this.AddEdge(enumerateValue2, (UpdateCommand)dynamicUpdateCommand);
                         }
                     }
                 }
             }
         }
         if (dynamicUpdateCommand.Operator == ModificationOperator.Update || ModificationOperator.Delete == dynamicUpdateCommand.Operator)
         {
             foreach (ReferentialConstraint enumerateValue1 in this._targetMap.EnumerateValues((EntitySetBase)dynamicUpdateCommand.Table))
             {
                 UpdateCommandOrderer.ForeignKeyValue key1;
                 UpdateCommandOrderer.ForeignKeyValue key2;
                 if (UpdateCommandOrderer.ForeignKeyValue.TryCreateTargetKey(enumerateValue1, dynamicUpdateCommand.OriginalValues, false, out key1) && (dynamicUpdateCommand.Operator != ModificationOperator.Update || !UpdateCommandOrderer.ForeignKeyValue.TryCreateTargetKey(enumerateValue1, dynamicUpdateCommand.CurrentValues, false, out key2) || !this._keyComparer.Equals(key2, key1)))
                 {
                     foreach (UpdateCommand enumerateValue2 in predecessors.EnumerateValues(key1))
                     {
                         if (enumerateValue2 != dynamicUpdateCommand)
                         {
                             this.AddEdge(enumerateValue2, (UpdateCommand)dynamicUpdateCommand);
                         }
                     }
                 }
             }
         }
     }
 }
Example #4
0
        private void InitializeFunctionMappingTranslators(
            EntitySetBase entitySetBase,
            EntityContainerMapping mapping)
        {
            KeyToListMap <AssociationSet, AssociationEndMember> keyToListMap = new KeyToListMap <AssociationSet, AssociationEndMember>((IEqualityComparer <AssociationSet>)EqualityComparer <AssociationSet> .Default);

            if (!this.m_functionMappingTranslators.ContainsKey(entitySetBase))
            {
                foreach (EntitySetMapping entitySetMap in mapping.EntitySetMaps)
                {
                    if (0 < entitySetMap.ModificationFunctionMappings.Count)
                    {
                        this.m_functionMappingTranslators.Add(entitySetMap.Set, ModificationFunctionMappingTranslator.CreateEntitySetTranslator(entitySetMap));
                        foreach (AssociationSetEnd associationSetEnd in entitySetMap.ImplicitlyMappedAssociationSetEnds)
                        {
                            AssociationSet parentAssociationSet = associationSetEnd.ParentAssociationSet;
                            if (!this.m_functionMappingTranslators.ContainsKey((EntitySetBase)parentAssociationSet))
                            {
                                this.m_functionMappingTranslators.Add((EntitySetBase)parentAssociationSet, ModificationFunctionMappingTranslator.CreateAssociationSetTranslator((AssociationSetMapping)null));
                            }
                            AssociationSetEnd oppositeEnd = MetadataHelper.GetOppositeEnd(associationSetEnd);
                            keyToListMap.Add(parentAssociationSet, oppositeEnd.CorrespondingAssociationEndMember);
                        }
                    }
                    else
                    {
                        this.m_functionMappingTranslators.Add(entitySetMap.Set, (ModificationFunctionMappingTranslator)null);
                    }
                }
                foreach (AssociationSetMapping relationshipSetMap in mapping.RelationshipSetMaps)
                {
                    if (relationshipSetMap.ModificationFunctionMapping != null)
                    {
                        AssociationSet set = (AssociationSet)relationshipSetMap.Set;
                        this.m_functionMappingTranslators.Add((EntitySetBase)set, ModificationFunctionMappingTranslator.CreateAssociationSetTranslator(relationshipSetMap));
                        keyToListMap.AddRange(set, Enumerable.Empty <AssociationEndMember>());
                    }
                    else if (!this.m_functionMappingTranslators.ContainsKey(relationshipSetMap.Set))
                    {
                        this.m_functionMappingTranslators.Add(relationshipSetMap.Set, (ModificationFunctionMappingTranslator)null);
                    }
                }
            }
            foreach (AssociationSet key in keyToListMap.Keys)
            {
                this.m_associationSetMetadata.Add(key, new AssociationSetMetadata(keyToListMap.EnumerateValues(key)));
            }
        }
 private void AddModelDependencies(
     KeyToListMap <EntityKey, UpdateCommand> producedMap,
     KeyToListMap <EntityKey, UpdateCommand> requiredMap)
 {
     foreach (KeyValuePair <EntityKey, List <UpdateCommand> > keyValuePair in requiredMap.KeyValuePairs)
     {
         EntityKey            key = keyValuePair.Key;
         List <UpdateCommand> updateCommandList = keyValuePair.Value;
         foreach (UpdateCommand enumerateValue in producedMap.EnumerateValues(key))
         {
             foreach (UpdateCommand to in updateCommandList)
             {
                 if (!object.ReferenceEquals((object)enumerateValue, (object)to) && (enumerateValue.Kind == UpdateCommandKind.Function || to.Kind == UpdateCommandKind.Function))
                 {
                     this.AddEdge(enumerateValue, to);
                 }
             }
         }
     }
 }
        // Loads and registers any function mapping translators for the given extent (and related container)
        private void InitializeFunctionMappingTranslators(EntitySetBase entitySetBase, EntityContainerMapping mapping)
        {
            var requiredEnds = new KeyToListMap <AssociationSet, AssociationEndMember>(
                EqualityComparer <AssociationSet> .Default);

            // see if function mapping metadata needs to be processed
            if (!m_functionMappingTranslators.ContainsKey(entitySetBase))
            {
                // load all function mapping data from the current entity container
                foreach (EntitySetMapping entitySetMapping in mapping.EntitySetMaps)
                {
                    if (0 < entitySetMapping.ModificationFunctionMappings.Count)
                    {
                        // register the function mapping
                        m_functionMappingTranslators.Add(
                            entitySetMapping.Set, ModificationFunctionMappingTranslator.CreateEntitySetTranslator(entitySetMapping));

                        // register "null" function translators for all implicitly mapped association sets
                        foreach (var end in entitySetMapping.ImplicitlyMappedAssociationSetEnds)
                        {
                            var associationSet = end.ParentAssociationSet;
                            if (!m_functionMappingTranslators.ContainsKey(associationSet))
                            {
                                m_functionMappingTranslators.Add(
                                    associationSet, ModificationFunctionMappingTranslator.CreateAssociationSetTranslator(null));
                            }

                            // Remember that the current entity set is required for all updates to the collocated
                            // relationship set. This entity set's end is opposite the target end for the mapping.
                            var oppositeEnd = MetadataHelper.GetOppositeEnd(end);
                            requiredEnds.Add(associationSet, oppositeEnd.CorrespondingAssociationEndMember);
                        }
                    }
                    else
                    {
                        // register null translator (so that we never attempt to process this extent again)
                        m_functionMappingTranslators.Add(entitySetMapping.Set, null);
                    }
                }

                foreach (AssociationSetMapping associationSetMapping in mapping.RelationshipSetMaps)
                {
                    if (null != associationSetMapping.ModificationFunctionMapping)
                    {
                        var set = (AssociationSet)associationSetMapping.Set;

                        // use indexer rather than Add since the association set may already have an implicit function
                        // mapping -- this explicit function mapping takes precedence in such cases
                        m_functionMappingTranslators.Add(
                            set,
                            ModificationFunctionMappingTranslator.CreateAssociationSetTranslator(associationSetMapping));

                        // remember that we've seen a function mapping for this association set, which overrides
                        // any other behaviors for determining required/optional ends
                        requiredEnds.AddRange(set, Enumerable.Empty <AssociationEndMember>());
                    }
                    else
                    {
                        if (!m_functionMappingTranslators.ContainsKey(associationSetMapping.Set))
                        {
                            // register null translator (so that we never attempt to process this extent again)
                            m_functionMappingTranslators.Add(associationSetMapping.Set, null);
                        }
                    }
                }
            }

            // register association metadata for all association sets encountered
            foreach (var associationSet in requiredEnds.Keys)
            {
                m_associationSetMetadata.Add(
                    associationSet, new AssociationSetMetadata(
                        requiredEnds.EnumerateValues(associationSet)));
            }
        }
Example #7
0
        // Finds all successors to the given predecessors and registers the resulting dependency edges in this
        // graph.
        //
        // - Commands (updates or inserts) inserting FK "sources" (referencing foreign key)
        // - Commands (updates or deletes) deleting FK "targets" (referenced by the foreign key)
        //
        // To avoid violating constraints, FK references must be created before their referees, and
        // cannot be deleted before their references.
        private void AddForeignKeyEdges(KeyToListMap <ForeignKeyValue, UpdateCommand> predecessors)
        {
            foreach (var command in Vertices.OfType <DynamicUpdateCommand>())
            {
                // register all source successors
                if (ModificationOperator.Update == command.Operator
                    ||
                    ModificationOperator.Insert == command.Operator)
                {
                    foreach (var fkConstraint in _sourceMap.EnumerateValues(command.Table))
                    {
                        ForeignKeyValue fk;
                        if (ForeignKeyValue.TryCreateSourceKey(fkConstraint, command.CurrentValues, true, out fk))
                        {
                            // if this is an update and the source key is unchanged, there is no
                            // need to add a dependency (from the perspective of the target, the update
                            // is a no-op)
                            ForeignKeyValue originalFK;
                            if (ModificationOperator.Update != command.Operator
                                ||
                                !ForeignKeyValue.TryCreateSourceKey(fkConstraint, command.OriginalValues, true, out originalFK)
                                ||
                                !_keyComparer.Equals(originalFK, fk))
                            {
                                foreach (var predecessor in predecessors.EnumerateValues(fk))
                                {
                                    // don't add self-edges for FK dependencies, since a single operation
                                    // in the store is atomic
                                    if (predecessor != command)
                                    {
                                        AddEdge(predecessor, command);
                                    }
                                }
                            }
                        }
                    }
                }

                // register all target successors
                if (ModificationOperator.Update == command.Operator
                    ||
                    ModificationOperator.Delete == command.Operator)
                {
                    foreach (var fkConstraint in _targetMap.EnumerateValues(command.Table))
                    {
                        ForeignKeyValue fk;
                        if (ForeignKeyValue.TryCreateTargetKey(fkConstraint, command.OriginalValues, false, out fk))
                        {
                            // if this is an update and the target key is unchanged, there is no
                            // need to add a dependency (from the perspective of the source, the update
                            // is a no-op)
                            ForeignKeyValue currentFK;
                            if (ModificationOperator.Update != command.Operator
                                ||
                                !ForeignKeyValue.TryCreateTargetKey(fkConstraint, command.CurrentValues, false, out currentFK)
                                ||
                                !_keyComparer.Equals(currentFK, fk))
                            {
                                foreach (var predecessor in predecessors.EnumerateValues(fk))
                                {
                                    // don't add self-edges for FK dependencies, since a single operation
                                    // in the store is atomic
                                    if (predecessor != command)
                                    {
                                        AddEdge(predecessor, command);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }