Пример #1
0
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            Debug.Assert(cpc != null, "InvokeInternal is called when EntityContainerMapping is null.");

            // safety check, this should never be hit
            if (EntityType == null)
            {
                throw new InvalidOperationException("InvokeInternal is called when entity type is null");
            }

            EntityType.Abstract.Value = SetAbstract;

            // remove any function mappings if we are setting this to abstract
            if (SetAbstract)
            {
                var etms = new List <EntityTypeMapping>();
                etms.AddRange(EntityType.GetAntiDependenciesOfType <EntityTypeMapping>());

                for (var i = etms.Count - 1; i >= 0; i--)
                {
                    var etm = etms[i];
                    if (etm != null &&
                        etm.Kind == EntityTypeMappingKind.Function)
                    {
                        DeleteEFElementCommand.DeleteInTransaction(cpc, etm);
                    }
                }
            }

            XmlModelHelper.NormalizeAndResolve(EntityType);
        }
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            if (String.IsNullOrEmpty(_longDescriptionText))
            {
                if (_efElement.Documentation != null &&
                    _efElement.Documentation.LongDescription != null)
                {
                    DeleteEFElementCommand.DeleteInTransaction(cpc, _efElement.Documentation.LongDescription);

                    // if the documentation node is empty, delete it
                    if (_efElement.Documentation.Summary == null)
                    {
                        DeleteEFElementCommand.DeleteInTransaction(cpc, _efElement.Documentation);
                    }
                }
            }
            else
            {
                if (_efElement.Documentation == null)
                {
                    _efElement.Documentation = new Documentation(_efElement, null);
                }

                if (_efElement.Documentation.LongDescription == null)
                {
                    _efElement.Documentation.LongDescription = new LongDescription(_efElement.Documentation, null);
                }

                _efElement.Documentation.LongDescription.Text = _longDescriptionText;

                XmlModelHelper.NormalizeAndResolve(_efElement);
            }
        }
Пример #3
0
        private static void ReplaceModelRoot(
            CommandProcessorContext cpc, EFRuntimeModelRoot existingModelRoot, XmlReader newSchemaReader,
            CreateModelRootCallback createModelRootCallback)
        {
            var newModelRootNode = XElement.Load(newSchemaReader);

            // find the XObject representing the existing EFRuntimeModelRoot EFObject
            var existingModelRootNode = existingModelRoot.XObject as XElement;

            Debug.Assert(existingModelRootNode != null, "existingRootXElement is null in ReplaceModelRoot()");

            // find the parent of the existing XObject tied to the EFRuntimeModelRoot
            var existingModelRootParentNode = existingModelRootNode.Parent;

            // delete the old EFRuntimeModelRoot EFObject but do not delete its anti-dependencies
            if (null != existingModelRoot)
            {
                var deleteConceptualModelCommand = new DeleteEFElementCommand(existingModelRoot, true, false);
                DeleteEFElementCommand.DeleteInTransaction(cpc, deleteConceptualModelCommand);
            }

            existingModelRootParentNode.Add(newModelRootNode);

            // Callback to create the EFRuntimeModelRoot EFObject
            createModelRootCallback(newModelRootNode);
        }
        private static void DeleteAllParameters(CommandProcessorContext cpc, FunctionImport fi)
        {
            IList <Parameter> parametersToDelete = new List <Parameter>();

            foreach (var parameter in fi.Parameters())
            {
                parametersToDelete.Add(parameter);
            }
            foreach (var parameter in parametersToDelete)
            {
                DeleteEFElementCommand.DeleteInTransaction(cpc, parameter);
            }
        }
Пример #5
0
 private static void DeleteMappingsForFunctions(CommandProcessorContext cpc, HashSet <Function> functions)
 {
     if (null != functions)
     {
         foreach (var f in functions)
         {
             foreach (var fim in f.GetAntiDependenciesOfType <FunctionImportMapping>())
             {
                 DeleteEFElementCommand.DeleteInTransaction(cpc, fim);
             }
         }
     }
 }
        protected override void PreInvoke(CommandProcessorContext cpc)
        {
            base.PreInvoke(cpc);

            // first make sure that we are changing the type
            if (_property != null &&
                _property.ComplexType.Target != _newType)
            {
                foreach (var cp in _property.GetAntiDependenciesOfType <ComplexProperty>())
                {
                    // delete all related ComplexProperty mappings when the property type changes
                    DeleteEFElementCommand.DeleteInTransaction(cpc, cp);
                }
            }
        }
Пример #7
0
        protected override void PostInvoke(CommandProcessorContext cpc)
        {
            // now that we have a new entity set, make sure that it and any derived types use correct MSL
            EnforceEntitySetMappingRules.AddRule(cpc, _derivedType.EntitySet);

            // see if this type is used by association ends; since we deleted the inheritance, this entity got
            // a new EntitySet so we need to change any EntitySet references for corresponding AssociationSetEnds to the new one
            Association association = null;

            foreach (var end in _derivedType.GetAntiDependenciesOfType <AssociationEnd>())
            {
                foreach (var setEnd in end.GetAntiDependenciesOfType <AssociationSetEnd>())
                {
                    setEnd.EntitySet.SetRefName(_derivedType.EntitySet);
                    XmlModelHelper.NormalizeAndResolve(setEnd);
                }

                association = end.Parent as Association;
            }

            // try to recreate the AssociationSetMapping if one exists
            if (association != null &&
                association.AssociationSet != null &&
                association.AssociationSet.AssociationSetMapping != null &&
                association.AssociationSet.AssociationSetMapping.XObject != null)
            {
                // store off the entity set for later
                var storeEntitySet = association.AssociationSet.AssociationSetMapping.StoreEntitySet.Target;

                // delete it
                DeleteEFElementCommand.DeleteInTransaction(cpc, association.AssociationSet.AssociationSetMapping);

                // create a new one (if we can)
                if (storeEntitySet != null &&
                    storeEntitySet.EntityType.Target != null)
                {
                    var set = storeEntitySet.EntityType.Target as StorageEntityType;
                    Debug.Assert(storeEntitySet.EntityType.Target == null || set != null, "EntityType is not StorageEntityType");

                    CreateAssociationSetMappingCommand.CreateAssociationSetMappingAndIntellimatch(cpc, association, set);
                }
            }

            base.PostInvoke(cpc);
        }
        protected override void PostInvoke(CommandProcessorContext cpc)
        {
            foreach (var property in _properties)
            {
                var deleteCommand         = property.GetDeleteCommand();
                var deletePropertyCommand = deleteCommand as DeletePropertyCommand;
                Debug.Assert(
                    deletePropertyCommand != null,
                    "Property.GetDeleteCommand() failed to return a DeletePropertyCommand, command translation will not receive the correct value for the IsConceptualDeleteOnly flag");

                if (deletePropertyCommand != null)
                {
                    deletePropertyCommand.IsConceptualOnlyDelete = true;
                }

                DeleteEFElementCommand.DeleteInTransaction(cpc, deletePropertyCommand);
            }
        }
Пример #9
0
        private static void DeleteMappingsForEntitySets(CommandProcessorContext cpc, HashSet <StorageEntitySet> storageEntitySets)
        {
            if (null != storageEntitySets)
            {
                foreach (var ses in storageEntitySets)
                {
                    foreach (var mappingFragment in ses.GetAntiDependenciesOfType <MappingFragment>())
                    {
                        DeleteEFElementCommand.DeleteInTransaction(cpc, mappingFragment);
                    }

                    foreach (var asm in ses.GetAntiDependenciesOfType <AssociationSetMapping>())
                    {
                        DeleteEFElementCommand.DeleteInTransaction(cpc, asm);
                    }
                }
            }
        }
        /// <summary>
        ///     We override this method to do some specialized processing of removing connectors associated with the shape.
        /// </summary>
        /// <param name="cpc"></param>
        protected override void RemoveAntiDeps(CommandProcessorContext cpc)
        {
            var associationConnectors = ModelHelper.GetListOfAssociationConnectorsForEntityTypeShape(EntityTypeShape).ToArray();

            foreach (var associationConnector in associationConnectors)
            {
                DeleteEFElementCommand.DeleteInTransaction(cpc, associationConnector);
            }

            var inheritanceConnectors = ModelHelper.GetListOfInheritanceConnectorsForEntityTypeShape(EntityTypeShape).ToArray();

            foreach (var inheritanceConnector in inheritanceConnectors)
            {
                DeleteEFElementCommand.DeleteInTransaction(cpc, inheritanceConnector);
            }

            // process the remaining antiDeps normally
            base.RemoveAntiDeps(cpc);
        }
Пример #11
0
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            // find the ordinal pair of this property ref in the dependent section

            var role = PropertyRef.Parent as ReferentialConstraintRole;

            if (role != null)
            {
                var rc = role.Parent as ReferentialConstraint;
                if (rc != null)
                {
                    // find the "other" ReferentialConstraint
                    var other = rc.Principal;
                    if (rc.Principal == role)
                    {
                        other = rc.Dependent;
                    }
                    Debug.Assert(
                        (other == rc.Principal && role == rc.Dependent) || (role == rc.Principal && other == rc.Dependent),
                        "Why aren't both RefConstraintRoles being used?");

                    //
                    //  Since principal & dependent property refs are paired up based on document order,
                    //  we get the ordinal position of the anti-dep element, and then find its peer
                    //
                    var i         = GetOrdinalPosition(PropertyRef);
                    var otherPRef = GetIthPropertyRef(other, i);

                    Debug.Assert(i == GetOrdinalPosition(otherPRef), "Unexpected ordinal positions for property refs!");

                    //
                    // we found the two peers to delete, so we want to delete them.
                    // don't call "DeleteInTransaction" here, as that will call GetDeleteCommand which will
                    // return this.  We want to use a straight "DeleteEFElementCommand" here.
                    //
                    Command cmd1 = new DeleteEFElementCommand(PropertyRef);
                    Command cmd2 = new DeleteEFElementCommand(otherPRef);
                    CommandProcessor.InvokeSingleCommand(cpc, cmd1);
                    CommandProcessor.InvokeSingleCommand(cpc, cmd2);
                }
            }
        }
Пример #12
0
        /// <summary>
        ///     Update the underlying function/store-procedure if they are changed.
        /// </summary>
        private void UpdateFunctionImportFunction(CommandProcessorContext cpc)
        {
            if (Function != FunctionImport.Function)
            {
                // if the user selected "(None)" then delete the FunctionImportMapping
                if (Function == null)
                {
                    DeleteEFElementCommand.DeleteInTransaction(cpc, FunctionImport.FunctionImportMapping);
                }

                // if the user selected another stored procedure, update the mapping
                // and the parameters of the function import
                else
                {
                    var functionImportMapping = FunctionImport.FunctionImportMapping;
                    if (functionImportMapping == null)
                    {
                        // if there isn't a FunctionImportMapping already, we need to create it with the FunctionName
                        if (FunctionImport.Artifact != null &&
                            FunctionImport.Artifact.MappingModel() != null &&
                            FunctionImport.Artifact.MappingModel().FirstEntityContainerMapping != null)
                        {
                            var cmdFuncImpMapping = new CreateFunctionImportMappingCommand(
                                FunctionImport.Artifact.MappingModel().FirstEntityContainerMapping,
                                Function,
                                FunctionImport);
                            CommandProcessor.InvokeSingleCommand(cpc, cmdFuncImpMapping);
                        }
                    }
                    else
                    {
                        // update the FunctionName in the FunctionImportMapping
                        functionImportMapping.FunctionName.SetRefName(Function);
                        AddToBeNormalizedEFContainerItem(functionImportMapping);
                    }
                }

                // finally, update the parameters of the function import to match the function
                CreateFunctionImportCommand.UpdateFunctionImportParameters(cpc, FunctionImport, Function);
            }
        }
        private static void DeleteStaleAssociations(CommandProcessorContext cpc, BaseEntityModel model, HashSet<string> associationNames)
        {
            Debug.Assert(model != null, "Model was null, could not delete stale Fks between Pks");
            if (model != null)
            {
                var associationsToDelete = new List<Association>();

                foreach (var association in model.Associations())
                {
                    // If this association is longer present in the latest SqlSchema model, delete it
                    if (associationNames.Contains(association.Name.Value) == false)
                    {
                        associationsToDelete.Add(association);
                    }
                }

                foreach (var association in associationsToDelete)
                {
                    var deleteAssociationSetCommand = new DeleteEFElementCommand(
                        (c, subCpc) =>
                            {
                                var cmd = c as DeleteEFElementCommand;
                                cmd.EFElement = ModelHelper.FindAssociationSet(model, association.Name.Value);
                                return cmd.EFElement != null;
                            });

                    CommandProcessor.InvokeSingleCommand(cpc, deleteAssociationSetCommand);

                    var deleteAssociationCmd = new DeleteAssociationCommand(
                        (c, subCpc) =>
                            {
                                var cmd = c as DeleteAssociationCommand;
                                // Checking the model again for the association in case it's deleted already.
                                cmd.EFElement = ModelHelper.FindAssociation(model, association.Name.Value);
                                return cmd.EFElement != null;
                            });

                    CommandProcessor.InvokeSingleCommand(cpc, deleteAssociationCmd);
                }
            }
        }
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            // find the ordinal pair of this property ref in the dependent section

            var role = PropertyRef.Parent as ReferentialConstraintRole;
            if (role != null)
            {
                var rc = role.Parent as ReferentialConstraint;
                if (rc != null)
                {
                    // find the "other" ReferentialConstraint
                    var other = rc.Principal;
                    if (rc.Principal == role)
                    {
                        other = rc.Dependent;
                    }
                    Debug.Assert(
                        (other == rc.Principal && role == rc.Dependent) || (role == rc.Principal && other == rc.Dependent),
                        "Why aren't both RefConstraintRoles being used?");

                    // 
                    //  Since principal & dependent property refs are paired up based on document order, 
                    //  we get the ordinal position of the anti-dep element, and then find its peer
                    //
                    var i = GetOrdinalPosition(PropertyRef);
                    var otherPRef = GetIthPropertyRef(other, i);

                    Debug.Assert(i == GetOrdinalPosition(otherPRef), "Unexpected ordinal positions for property refs!");

                    //
                    // we found the two peers to delete, so we want to delete them.
                    // don't call "DeleteInTransaction" here, as that will call GetDeleteCommand which will
                    // return this.  We want to use a straight "DeleteEFElementCommand" here.
                    //
                    Command cmd1 = new DeleteEFElementCommand(PropertyRef);
                    Command cmd2 = new DeleteEFElementCommand(otherPRef);
                    CommandProcessor.InvokeSingleCommand(cpc, cmd1);
                    CommandProcessor.InvokeSingleCommand(cpc, cmd2);
                }
            }
        }
Пример #15
0
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            // recycle connectors to avoid having rebinding the model
            var connectorPoints = new List <ConnectorPoint>(_connector.ConnectorPoints);

            if (connectorPoints.Count > _edgePoints.Count)
            {
                var diff = _connector.ConnectorPoints.Count - _edgePoints.Count;
                for (var i = 0; i < diff; i++)
                {
                    var lastIdx = connectorPoints.Count - 1;
                    var cp      = connectorPoints[lastIdx];
                    DeleteEFElementCommand.DeleteInTransaction(cpc, cp);
                    connectorPoints.RemoveAt(lastIdx);
                }
            }
            else if (connectorPoints.Count < _edgePoints.Count)
            {
                var diff = _edgePoints.Count - connectorPoints.Count;
                for (var i = 0; i < diff; i++)
                {
                    var cp = new ConnectorPoint(_connector, null);
                    _connector.AddConnectorPoint(cp);
                    XmlModelHelper.NormalizeAndResolve(cp);
                    connectorPoints.Add(cp);
                }
            }

            Debug.Assert(connectorPoints.Count == _edgePoints.Count, "ConnectorPoints.Count != edgePoints.Count");

            // be safe if the assert above fires, only go through min indices
            var min = Math.Min(_edgePoints.Count, connectorPoints.Count);

            for (var i = 0; i < min; i++)
            {
                var edgePoint      = _edgePoints[i];
                var connectorPoint = connectorPoints[i];
                connectorPoint.PointX.Value = edgePoint.Key;
                connectorPoint.PointY.Value = edgePoint.Value;
            }
        }
Пример #16
0
        private static void DeleteStaleAssociations(CommandProcessorContext cpc, BaseEntityModel model, HashSet <string> associationNames)
        {
            Debug.Assert(model != null, "Model was null, could not delete stale Fks between Pks");
            if (model != null)
            {
                var associationsToDelete = new List <Association>();

                foreach (var association in model.Associations())
                {
                    // If this association is longer present in the latest SqlSchema model, delete it
                    if (associationNames.Contains(association.Name.Value) == false)
                    {
                        associationsToDelete.Add(association);
                    }
                }

                foreach (var association in associationsToDelete)
                {
                    var deleteAssociationSetCommand = new DeleteEFElementCommand(
                        (c, subCpc) =>
                    {
                        var cmd       = c as DeleteEFElementCommand;
                        cmd.EFElement = ModelHelper.FindAssociationSet(model, association.Name.Value);
                        return(cmd.EFElement != null);
                    });

                    CommandProcessor.InvokeSingleCommand(cpc, deleteAssociationSetCommand);

                    var deleteAssociationCmd = new DeleteAssociationCommand(
                        (c, subCpc) =>
                    {
                        var cmd = c as DeleteAssociationCommand;
                        // Checking the model again for the association in case it's deleted already.
                        cmd.EFElement = ModelHelper.FindAssociation(model, association.Name.Value);
                        return(cmd.EFElement != null);
                    });

                    CommandProcessor.InvokeSingleCommand(cpc, deleteAssociationCmd);
                }
            }
        }
Пример #17
0
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            Debug.Assert(null != _entitySets, "Null entitySets in DeleteUnmappedStorageEntitySetsCommand.InvokeInternal()");
            if (null == _entitySets)
            {
                return;
            }

            // loop over the unmapped StorageEntitySets deleting them, also create
            // a list of any StorageEntityTypes referenced by these StorageEntitySets
            // Note: have to convert to array first to prevent exceptions due to
            // editing the collection while iterating over it
            var entitySets      = _entitySets.ToArray();
            var entityTypesList = new List <StorageEntityType>();

            foreach (var entitySet in entitySets)
            {
                // find any EntityType which is referenced by this EntitySet
                if (null != entitySet.EntityType &&
                    null != entitySet.EntityType.Target)
                {
                    var et = entitySet.EntityType.Target as StorageEntityType;
                    if (null != et)
                    {
                        entityTypesList.Add(et);
                    }
                }

                DeleteEFElementCommand.DeleteInTransaction(cpc, entitySet);
            }

            // delete all StorageEntityTypes found above
            var entityTypes = entityTypesList.ToArray();

            foreach (var entityType in entityTypes)
            {
                DeleteEFElementCommand.DeleteInTransaction(cpc, entityType);
            }
        }
Пример #18
0
        private static void ReplaceSsdl(CommandProcessorContext cpc, EntityDesignArtifact existingArtifact, XElement newSsdl)
        {
            // find the XObject representing the existing StorageModel Schema element
            var existingStorageModelNode = existingArtifact.StorageModel.XObject as XElement;

            Debug.Assert(existingStorageModelNode != null, "existingStorageModelNode is null");

            // find the parent of the existing StorageModel Schema element
            var existingStorageModelParentNode = existingStorageModelNode.Parent;

            // delete the old StorageModel but do not delete its anti-dependencies
            if (null != existingArtifact.StorageModel)
            {
                var deleteStorageModelCommand = new DeleteEFElementCommand(existingArtifact.StorageModel, true, false);
                DeleteEFElementCommand.DeleteInTransaction(cpc, deleteStorageModelCommand);
            }

            // this will clone the source element
            var ssdlSchemaElement = new XElement(newSsdl);

            // add ssdlSchemaElement to the parent of the previously existing Storage node
            existingStorageModelParentNode.Add(ssdlSchemaElement);

            // create a new StorageModel object, add it back into the artifact and re-parse
            existingArtifact.StorageModel = new StorageEntityModel(existingArtifact, ssdlSchemaElement);
            existingArtifact.StorageModel.Parse(new HashSet <XName>());
            Debug.Assert(
                EFElementState.Parsed == existingArtifact.StorageModel.State,
                "StorageModel State should be Parsed, instead it is " + existingArtifact.StorageModel.State);

            // normalize and resolve the StorageModel
            XmlModelHelper.NormalizeAndResolve(existingArtifact.StorageModel);
            Debug.Assert(
                EFElementState.Resolved == existingArtifact.StorageModel.State,
                "StorageModel State should be Resolved, instead it is " + existingArtifact.StorageModel.State);
        }
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            // safety check, this should never be hit
            Debug.Assert(
                EntityToBeDerived != null && BaseType != null, "InvokeInternal is called when EntityToBeDerived or BaseType is null");

            if (EntityToBeDerived == null ||
                BaseType == null)
            {
                throw new InvalidOperationException("InvokeInternal is called when EntityToBeDerived or BaseType is null");
            }

            if (EntityToBeDerived.EntitySet != null)
            {
                // since we are creating an inheritance, we need to delete EntitySet(s) for entityToBeDerived,
                // before we do this, move any EntityTypeMappings to the base type's EntitySetMapping
                var entitySetToDelete        = EntityToBeDerived.EntitySet as ConceptualEntitySet;
                var entitySetMappingToDelete = entitySetToDelete.EntitySetMapping;

                // if there isn't an ESM, there won't be anything to move
                if (entitySetMappingToDelete != null)
                {
                    var entitySetOfBaseType = BaseType.EntitySet as ConceptualEntitySet;
                    if (entitySetOfBaseType != null)
                    {
                        // get the base type's ESM (if it doesn't exist, create one)
                        var entitySetMappingOfBaseType = entitySetOfBaseType.EntitySetMapping;
                        if (entitySetMappingOfBaseType == null)
                        {
                            var entityContainer = EntityToBeDerived.EntityModel.EntityContainer;
                            Debug.Assert(entityContainer != null, "EntityToBeDerived should have an Entity Container");

                            var createESM = new CreateEntitySetMappingCommand(entityContainer.EntityContainerMapping, entitySetOfBaseType);
                            CommandProcessor.InvokeSingleCommand(cpc, createESM);
                            entitySetMappingOfBaseType = createESM.EntitySetMapping;
                        }

                        // move all of the ETMs
                        var etms = new List <EntityTypeMapping>();
                        etms.AddRange(entitySetMappingToDelete.EntityTypeMappings());

                        foreach (var etm in etms)
                        {
                            // here, to work around an xml editor bug, we clone the entity type mapping, instead of re-parenting it
                            etm.Clone(entitySetMappingOfBaseType);

                            // The old EntityTyepMapping will be deleted when we delete the entity set below.
                        }
                    }
                }

                // now we can delete the entity set, which will delete the ESM too
                DeleteEFElementCommand.DeleteInTransaction(cpc, entitySetToDelete);
            }

            // remove all properties from derived entity's key (it will inherit the base type's keys now)
            if (EntityToBeDerived.Key != null)
            {
                var propertyRefs = new List <PropertyRef>(EntityToBeDerived.Key.PropertyRefs);
                foreach (var propertyRef in propertyRefs)
                {
                    var property = propertyRef.Name.Target;
                    if (property != null)
                    {
                        var setKey = new SetKeyPropertyCommand(property, false, false, true);
                        CommandProcessor.InvokeSingleCommand(cpc, setKey);
                    }
                }
            }

            // set the base type
            EntityToBeDerived.BaseType.SetRefName(BaseType);

            //
            // if there is a referential constraint, then update any principals in the ref constraint to
            // point to properties in the new entity type.
            //
            foreach (var end in EntityToBeDerived.GetAntiDependenciesOfType <AssociationEnd>())
            {
                foreach (var role in end.GetAntiDependenciesOfType <ReferentialConstraintRole>())
                {
                    var rc = role.Parent as ReferentialConstraint;
                    if (rc != null &&
                        rc.Principal == role)
                    {
                        //
                        // this is the principal, so we want to update any keys in RC to reflect new keys
                        // in the new base type.  If the number of keys don't match, we'll delete any leftovers
                        //
                        var keys = BaseType.ResolvableTopMostBaseType.ResolvableKeys.GetEnumerator();
                        foreach (var pr in rc.Principal.PropertyRefs)
                        {
                            if (keys.MoveNext())
                            {
                                // update this property ref to reflect the new key in the derived type
                                pr.Name.SetRefName(keys.Current);
                                ItemBinding[] bindings = { pr.Name };
                                CheckArtifactBindings.ScheduleBindingsForRebind(cpc, bindings);
                            }
                            else
                            {
                                // no more keys in the new base type, so delete this property ref & it's peer
                                // in the dependent section
                                Command cmd = new DeleteReferentialConstraintPropertyRefCommand(pr);
                                // don't invoke this command now, as it will modify the collection we're iterating over
                                CommandProcessor.EnqueueCommand(cmd);
                            }
                        }
                    }
                }
            }

            // rebind and verify
            EntityToBeDerived.BaseType.Rebind();
            Debug.Assert(
                EntityToBeDerived.BaseType.Status == BindingStatus.Known,
                "EntityToBeDerived.BaseType.Status should be BindingStatus.Known, instead it is "
                + EntityToBeDerived.BaseType.Status.ToString());
        }
        protected override void PreInvoke(CommandProcessorContext cpc)
        {
            base.PreInvoke(cpc);

            // you cannot use this command with a type that already has a base class; throwing here
            // because its not a good idea to throw an exception in a c'tor
            if (EntityToBeDerived == null ||
                EntityToBeDerived.BaseType.Target != null)
            {
                throw new InvalidOperationException();
            }

            EnforceEntitySetMappingRules.AddRule(cpc, BaseType.EntitySet);

            // see if this type is used by association ends; since we are creating an inheritance
            // we need to change any AssociationSetEnd references from the current EntitySet to the
            // new baseType's EntitySet (the derived type's EntitySet will be deleted)
            var associationsToUpdate = new HashSet <Association>();

            if (EntityToBeDerived.EntitySet != null)
            {
                var associationSetEndsToUpdate = EntityToBeDerived.EntitySet.GetAntiDependenciesOfType <AssociationSetEnd>();
                foreach (var setEnd in associationSetEndsToUpdate)
                {
                    setEnd.EntitySet.SetRefName(BaseType.EntitySet);
                    XmlModelHelper.NormalizeAndResolve(setEnd);

                    var aSet = setEnd.Parent as AssociationSet;
                    if (aSet != null)
                    {
                        if (aSet.Association.Target != null)
                        {
                            associationsToUpdate.Add(aSet.Association.Target);
                        }
                    }
                }
            }

            foreach (var association in associationsToUpdate)
            {
                // try to recreate the AssociationSetMapping if one exists
                if (association != null &&
                    association.AssociationSet != null &&
                    association.AssociationSet.AssociationSetMapping != null &&
                    association.AssociationSet.AssociationSetMapping.XObject != null)
                {
                    // store off the entity set for later
                    var storeEntitySet = association.AssociationSet.AssociationSetMapping.StoreEntitySet.Target;

                    // delete it
                    DeleteEFElementCommand.DeleteInTransaction(cpc, association.AssociationSet.AssociationSetMapping);

                    // create a new one (if we can)
                    if (storeEntitySet != null &&
                        storeEntitySet.EntityType.Target != null)
                    {
                        var set = storeEntitySet.EntityType.Target as StorageEntityType;
                        Debug.Assert(set != null, "EntityType is not StorageEntityType");
                        CreateAssociationSetMappingCommand.CreateAssociationSetMappingAndIntellimatch(cpc, association, set);
                    }
                }
            }
        }
        /// <summary>
        ///     If this element has any children that have unresolved references
        ///     or has itself an unresolved reference then Delete the element
        ///     NB: Be warned this method is destructive. If you have unbound
        ///     elements for whatever reason then those elements will be removed.
        /// </summary>
        private static void RecursiveDeleteUnboundElements(CommandProcessorContext cpc, EFElement efElement)
        {
            var mappingCondition = efElement as Condition;
            var queryView        = efElement as QueryView;

            if (mappingCondition != null)
            {
                // A Mapping Condition is special because it will
                // only ever have 1 bound child out of 2
                var children = efElement.Children.ToArray();
                var anyOneOfChildrenIsBound =
                    children.OfType <ItemBinding>().Any(itemBinding => itemBinding.Resolved);

                if (!anyOneOfChildrenIsBound)
                {
                    DeleteEFElementCommand.DeleteInTransaction(cpc, efElement);
                }

                return;
            }
            else if (queryView != null)
            {
                // QueryView elements have a TypeName attribute, but it is optional and
                // so the QueryView should not be deleted even if the TypeName attribute
                // is not in a Resolved state
                return;
            }
            else
            {
                // cannot use IEnumerable directly as we are potentially
                // deleting from the returned collection
                var children = new List <EFObject>(efElement.Children);

                // remove any children which are optional (and hence not being resolved does not require a delete)
                var cp = efElement as ComplexProperty;
                if (cp != null)
                {
                    // TypeName binding in ComplexProperty is optional and can be unresolved, so remove it from the check list
                    children.Remove(cp.TypeName);
                }
                var mf = efElement as ModificationFunction;
                if (mf != null)
                {
                    children.Remove(mf.RowsAffectedParameter);
                }

                // loop over children and recursively delete
                foreach (var child in children)
                {
                    var efElementChild   = child as EFElement;
                    var itemBindingChild = child as ItemBinding;
                    if (efElementChild != null)
                    {
                        RecursiveDeleteUnboundElements(cpc, efElementChild);
                    }
                    else if (itemBindingChild != null)
                    {
                        if (!itemBindingChild.Resolved)
                        {
                            DeleteEFElementCommand.DeleteInTransaction(cpc, efElement);
                            return;
                        }
                    }
                }
            }
        }
Пример #22
0
 internal override DeleteEFElementCommand GetDeleteCommand()
 {
     var cmd = new DeleteEFElementCommand(this);
     if (cmd == null)
     {
         throw new InvalidOperationException();
     }
     return cmd;
 }
Пример #23
0
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            // safety check, this should never be hit
            Debug.Assert(_derivedType != null, "InvokeInternal is called when DerivedType is null.");
            if (_derivedType == null)
            {
                throw new InvalidOperationException("InvokeInternal is called when DerivedType is null.");
            }

            // store off some local variables
            var baseType             = _derivedType.BaseType.Target;
            var baseEntitySet        = baseType.EntitySet as ConceptualEntitySet;
            var baseEntitySetMapping = (baseEntitySet == null ? null : baseEntitySet.EntitySetMapping);

            // save off a HashSet of all base types up the inheritance tree for searching later
            var allBaseTypes = new HashSet <EntityType>();

            for (var baseEntityType = baseType; baseEntityType != null; baseEntityType = baseEntityType.BaseType.Target)
            {
                allBaseTypes.Add(baseEntityType);
            }

            // set up list of all derived types down the inheritance tree
            var derivedAndAllDerivedTypes = new List <ConceptualEntityType>();

            derivedAndAllDerivedTypes.Add(_derivedType);
            derivedAndAllDerivedTypes.AddRange(_derivedType.ResolvableAllDerivedTypes);

            // remove any mappings which refer to properties which were inherited as these will
            // no longer be valid when the inheritance is deleted (and would cause the Mapping Details
            // window to open in non-edit mode). This must be done _before_ proceeding to clone the
            // EntityTypeMapping below and before we delete the inheritance (i.e. before the
            // DefaultableValue Target becomes unresolved).
            var scalarPropsToDelete = new List <ScalarProperty>();

            if (allBaseTypes.Count > 0)
            {
                foreach (EntityType et in derivedAndAllDerivedTypes)
                {
                    foreach (var etm in et.GetAntiDependenciesOfType <EntityTypeMapping>())
                    {
                        foreach (var mf in etm.MappingFragments())
                        {
                            foreach (var sp in mf.AllScalarProperties())
                            {
                                var prop = sp.Name.Target;
                                if (prop != null)
                                {
                                    // find EntityType of which this Property is a member
                                    var propEntityType = prop.GetParentOfType(typeof(EntityType)) as EntityType;
                                    if (propEntityType != null &&
                                        allBaseTypes.Contains(propEntityType))
                                    {
                                        // sp references a Property of an EntityType which will no longer
                                        // be in the inheritance hierarchy - so delete the mapping
                                        scalarPropsToDelete.Add(sp);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            // cannot delete the ScalarProperty while enumerating over them - so instead delete in separate loop below
            foreach (var sp in scalarPropsToDelete)
            {
                DeleteEFElementCommand.DeleteInTransaction(cpc, sp);
            }

            // remove the inheritance
            _derivedType.BaseType.SetRefName(null);

            // re-resolve the derived type.  This will set the state of the _derivedType to be resolved (it could be unresolved because base-type binding could have been a duplicate or unknown binding).
            _derivedType.State = EFElementState.Normalized;
            _derivedType.Resolve(_derivedType.Artifact.ArtifactSet);

            // the entity container we want to add it to
            var entityContainer = _derivedType.EntityModel.EntityContainer;

            Debug.Assert(entityContainer != null, "DerivedType does not have an Entity Container");

            // since this type no longer derives, it is stand alone and needs its own entity set
            // derive a name for the new entity set and create it
            var trialSetName = ModelHelper.ConstructProposedEntitySetName(_derivedType.Artifact, _derivedType.LocalName.Value);
            var ces          = new CreateEntitySetCommand(trialSetName, _derivedType, true);

            CommandProcessor.InvokeSingleCommand(cpc, ces);
            var newEntitySet = ces.EntitySet as ConceptualEntitySet;

            // if the old entityset had mappings, then some may need to be moved
            if (baseEntitySetMapping != null)
            {
                // create a new EntitySetMapping for the new EntitySet that we made for the formally derivedType
                var createESM = new CreateEntitySetMappingCommand(entityContainer.EntityContainerMapping, newEntitySet);
                CommandProcessor.InvokeSingleCommand(cpc, createESM);
                var newEntitySetMapping = createESM.EntitySetMapping;

                // this type no longer derives from the type it used to, so its mappings can no longer
                // exist under the old EntitySetMapping, so we need to move them
                // move any EntityTypeMappings from the old EntitySetMapping used by the former base type
                // to the new one created for the new EntitySet and EntitySetMapping
                foreach (EntityType changingType in derivedAndAllDerivedTypes)
                {
                    var etms = new List <EntityTypeMapping>();
                    etms.AddRange(changingType.GetAntiDependenciesOfType <EntityTypeMapping>());

                    foreach (var etm in etms)
                    {
                        // here, to work around an xml editor bug, we clone the entity type mapping, instead of re-parenting it
                        var newetm = etm.Clone(newEntitySetMapping);

                        // now delete the old entity type mapping & dispose it.
                        DeleteEFElementCommand.DeleteInTransaction(cpc, etm);
                    }
                }
            }

            //
            //  if there are any referential constraints properties whose principal ends refer to keys in the
            //  old derived type, delete them
            //
            foreach (var end in _derivedType.GetAntiDependenciesOfType <AssociationEnd>())
            {
                foreach (var role in end.GetAntiDependenciesOfType <ReferentialConstraintRole>())
                {
                    var rc = role.Parent as ReferentialConstraint;
                    if (rc != null &&
                        rc.Principal == role)
                    {
                        foreach (var pr in rc.Principal.PropertyRefs)
                        {
                            Command cmd = new DeleteReferentialConstraintPropertyRefCommand(pr);
                            // don't invoke this command now, as it will modify the collection we're iterating over
                            CommandProcessor.EnqueueCommand(cmd);
                        }
                    }
                }
            }
        }
Пример #24
0
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            // safety check, this should never be hit
            Debug.Assert(Property != null, "InvokeInternal is called when property is null.");
            if (Property == null)
            {
                throw new InvalidOperationException("InvokeInternal is called when Property is null.");
            }

            if (Property.IsKeyProperty == IsKey)
            {
                // no change needed
                return;
            }

            if (IsKey)
            {
                if (Property.EntityType.Key == null)
                {
                    Property.EntityType.Key = new Key(Property.EntityType, null);
                }

                // make the key property non-nullable
                Property.Nullable.Value = BoolOrNone.FalseValue;
                Property.EntityType.Key.AddPropertyRef(Property);

                // normalize & resolve the key property
                XmlModelHelper.NormalizeAndResolve(Property.EntityType.Key);
            }
            else
            {
                var keyElement = Property.EntityType.Key;
                Debug.Assert(keyElement != null, "keyElement should not be null");

                if (keyElement != null)
                {
                    keyElement.RemovePropertyRef(Property);

                    if (!keyElement.Children.Any())
                    {
                        keyElement.Delete();
                    }
                    else
                    {
                        XmlModelHelper.NormalizeAndResolve(keyElement);
                    }
                }

                // if we are changing from key to non-key and this key is referenced by a principal end of
                // a ref constraint, then we want to delete that entry in the ref constraint
                if (IsKey == false && _deletePrincipalRCRefs)
                {
                    foreach (var pref in Property.GetAntiDependenciesOfType <PropertyRef>())
                    {
                        if (pref != null)
                        {
                            var role = pref.Parent as ReferentialConstraintRole;
                            if (role != null)
                            {
                                var rc = role.Parent as ReferentialConstraint;
                                if (rc != null &&
                                    rc.Principal == role)
                                {
                                    // property ref on a principal end, so delete it
                                    DeleteEFElementCommand.DeleteInTransaction(cpc, pref);
                                }
                            }
                        }
                    }
                }
            }

            var cet = Property.EntityType as ConceptualEntityType;

            if (cet != null)
            {
                PropagateViewKeysToStorageModel.AddRule(cpc, cet);
            }
        }
Пример #25
0
        /// <summary>
        ///     Update function import return type if requested.
        /// </summary>
        private void UpdateFunctionImportReturnType(CommandProcessorContext cpc)
        {
            if (ChangeReturnType)
            {
                // figure out if we are using a complex type, an entity type, primitive type or none as the return type
                var complexType = ReturnSingleType as ComplexType;
                var entityType  = ReturnSingleType as EntityType;
                // if returnTypeStringValue is not null, the value could be "None" or the string representation of primitive types (for example: "string", "Int16").
                var returnTypeStringValue = ReturnSingleType as string;

                // Only delete type-mapping if the function-import's return-type does not match type-mapping's type.
                var functionImportMapping = FunctionImport.FunctionImportMapping;
                if (functionImportMapping != null &&
                    functionImportMapping.ResultMapping != null)
                {
                    foreach (var typeMapping in functionImportMapping.ResultMapping.TypeMappings().ToList())
                    {
                        // If the old type mapping is FunctionImportComplexTypeMapping and function import does not return a complex type
                        // or return a different complex type.
                        if (typeMapping is FunctionImportComplexTypeMapping &&
                            (complexType == null ||
                             !String.Equals(typeMapping.TypeName.Target.DisplayName,
                                            complexType.DisplayName, StringComparison.CurrentCulture)))
                        {
                            DeleteEFElementCommand.DeleteInTransaction(cpc, typeMapping);
                        }
                        // If the old type mapping is FunctionImportEntityTypeMapping and function import does not return an entity type
                        // or return a different entity type.
                        else if (typeMapping is FunctionImportEntityTypeMapping &&
                                 (entityType == null ||
                                  !String.Equals(typeMapping.TypeName.Target.DisplayName,
                                                 entityType.DisplayName, StringComparison.CurrentCulture)))
                        {
                            DeleteEFElementCommand.DeleteInTransaction(cpc, typeMapping);
                        }
                    }
                    // If ResultMapping does not contain any type mappings, delete it.
                    if (functionImportMapping.ResultMapping.TypeMappings().Count == 0)
                    {
                        DeleteEFElementCommand.DeleteInTransaction(cpc, functionImportMapping.ResultMapping);
                    }
                }

                // we won't do any equality checking here against the original function import's return type
                // because we would expend cycles determining the 'collection' string, etc.
                string updatedReturnTypeAsString = null;
                if (entityType != null)
                {
                    // Return type could be a collection of EntityType, ComplexType or primitive type.
                    // If we change from the return type from a complex type to an entity type, we need to remove the complex type binding in the function import.
                    // Check if complex type binding is not null and reset it.
                    if (FunctionImport.ReturnTypeAsComplexType != null)
                    {
                        FunctionImport.ReturnTypeAsComplexType.SetRefName(null);
                        FunctionImport.ReturnTypeAsComplexType.Rebind();
                    }

                    // if we are using an entity type, the return type is "Collection(entityType)"
                    Debug.Assert(entityType.EntitySet != null, "Entity Type doesn't have an Entity Set we can use for the Function Import");
                    if (entityType.EntitySet != null)
                    {
                        FunctionImport.EntitySet.SetRefName(entityType.EntitySet);
                        FunctionImport.EntitySet.Rebind();
                        FunctionImport.ReturnTypeAsEntityType.SetRefName(entityType);
                        FunctionImport.ReturnTypeAsEntityType.Rebind();
                    }
                }
                else if (complexType != null)
                {
                    // if we change from an entity type to any other type, we need to remove the EntitySet binding on the FunctionImport
                    if (FunctionImport.EntitySet.RefName != null)
                    {
                        FunctionImport.EntitySet.SetRefName(null);
                        FunctionImport.EntitySet.Rebind();
                    }

                    FunctionImport.ReturnTypeAsComplexType.SetRefName(complexType);
                    FunctionImport.ReturnTypeAsComplexType.Rebind();
                }
                else
                {
                    // Return type could be a collection of EntityType, ComplexType or primitive type.
                    // If we change from the return type from a complex type to a primitive type, we need to remove the complex type binding in the function import.
                    // Check if complex type binding is not null and reset it.
                    if (FunctionImport.ReturnTypeAsComplexType != null)
                    {
                        FunctionImport.ReturnTypeAsComplexType.SetRefName(null);
                        FunctionImport.ReturnTypeAsComplexType.Rebind();
                    }

                    // if we change from an entity type to any other type, we need to remove the EntitySet binding on the FunctionImport
                    if (FunctionImport.EntitySet.RefName != null)
                    {
                        FunctionImport.EntitySet.SetRefName(null);
                        FunctionImport.EntitySet.Rebind();
                    }

                    // if the new value is 'None' then set the return type to null
                    if (returnTypeStringValue != Tools.XmlDesignerBase.Resources.NoneDisplayValueUsedForUX)
                    {
                        updatedReturnTypeAsString = String.Format(
                            CultureInfo.InvariantCulture, FunctionImport.CollectionFormat, returnTypeStringValue);
                    }

                    // update the actual return type of the function import
                    FunctionImport.ReturnTypeAsPrimitiveType.Value = updatedReturnTypeAsString;
                }
            }
        }
        private static void ReplaceModelRoot(
            CommandProcessorContext cpc, EFRuntimeModelRoot existingModelRoot, XmlReader newSchemaReader,
            CreateModelRootCallback createModelRootCallback)
        {
            var newModelRootNode = XElement.Load(newSchemaReader);

            // find the XObject representing the existing EFRuntimeModelRoot EFObject
            var existingModelRootNode = existingModelRoot.XObject as XElement;
            Debug.Assert(existingModelRootNode != null, "existingRootXElement is null in ReplaceModelRoot()");

            // find the parent of the existing XObject tied to the EFRuntimeModelRoot
            var existingModelRootParentNode = existingModelRootNode.Parent;

            // delete the old EFRuntimeModelRoot EFObject but do not delete its anti-dependencies
            if (null != existingModelRoot)
            {
                var deleteConceptualModelCommand = new DeleteEFElementCommand(existingModelRoot, true, false);
                DeleteEFElementCommand.DeleteInTransaction(cpc, deleteConceptualModelCommand);
            }

            existingModelRootParentNode.Add(newModelRootNode);

            // Callback to create the EFRuntimeModelRoot EFObject
            createModelRootCallback(newModelRootNode);
        }
Пример #27
0
 /// <summary>
 ///     This will create a transaction if there isn't one already.  If the CommandProcessorContext is already
 ///     tracking a transaction, then a new one is NOT created.
 /// </summary>
 /// <param name="cpc"></param>
 /// <param name="element">The EFElement to delete</param>
 /// <param name="rebindAllBindings">Control whether all bindings in the artifact should be rebound</param>
 internal static void DeleteInTransaction(CommandProcessorContext cpc, DeleteEFElementCommand cmd, bool rebindAllBindings)
 {
     cmd.RebindAllBindings = rebindAllBindings;
     CommandProcessor.InvokeSingleCommand(cpc, cmd);
 }
Пример #28
0
 /// <summary>
 ///     This will create a transaction if there isn't one already. If the CommandProcessorContext is already
 ///     tracking a transaction, then a new one is NOT created. This specific overload allows modifying the
 ///     command before invoking it (i.e. adding a PostInvokeEvent)
 /// </summary>
 /// <param name="cpc"></param>
 /// <param name="cmd"></param>
 internal static void DeleteInTransaction(CommandProcessorContext cpc, DeleteEFElementCommand cmd)
 {
     DeleteInTransaction(cpc, cmd, true);
 }
 /// <summary>
 ///     This will create a transaction if there isn't one already. If the CommandProcessorContext is already
 ///     tracking a transaction, then a new one is NOT created. This specific overload allows modifying the
 ///     command before invoking it (i.e. adding a PostInvokeEvent)
 /// </summary>
 /// <param name="cpc"></param>
 /// <param name="cmd"></param>
 internal static void DeleteInTransaction(CommandProcessorContext cpc, DeleteEFElementCommand cmd)
 {
     DeleteInTransaction(cpc, cmd, true);
 }
 /// <summary>
 ///     This will create a transaction if there isn't one already.  If the CommandProcessorContext is already
 ///     tracking a transaction, then a new one is NOT created.
 /// </summary>
 /// <param name="cpc"></param>
 /// <param name="element">The EFElement to delete</param>
 /// <param name="rebindAllBindings">Control whether all bindings in the artifact should be rebound</param>
 internal static void DeleteInTransaction(CommandProcessorContext cpc, DeleteEFElementCommand cmd, bool rebindAllBindings)
 {
     cmd.RebindAllBindings = rebindAllBindings;
     CommandProcessor.InvokeSingleCommand(cpc, cmd);
 }
Пример #31
0
 internal virtual DeleteEFElementCommand GetDeleteCommand()
 {
     var cmd = new DeleteEFElementCommand(this);
     if (cmd == null)
     {
         // shouldn't happen, just to be safe
         throw new InvalidOperationException();
     }
     return cmd;
 }