protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            if (!string.IsNullOrEmpty(Role) &&
                !string.Equals(End.Role.Value, Role, StringComparison.Ordinal))
            {
                // TODO:  should this command be enqueued in the command processor?
                RenameCommand c = new EntityDesignRenameCommand(End, Role, true);
                CommandProcessor.InvokeSingleCommand(cpc, c);

                // bug 563525: we need to update EndProperties within AssociationSetMappings if the AssociationEnd changes.
                // we update the "Role" of an AssociationSetEnd in the RenameCommand but the SingleItemBinding that we have to update
                // that is bound to the AssociationSetEnd is unique to this situation; it is not technically a "refactor rename".
                var associationSetEnd = End.GetAntiDependenciesOfType <AssociationSetEnd>().FirstOrDefault();

                if (associationSetEnd != null)
                {
                    // we need to renormalize the associationSetEnd, since the role name will have changed.
                    XmlModelHelper.NormalizeAndResolve(associationSetEnd);

                    var endPropertiesInAssocSetMappings = associationSetEnd.GetAntiDependenciesOfType <EndProperty>();
                    foreach (var endProperty in endPropertiesInAssocSetMappings)
                    {
                        endProperty.Name.SetRefName(associationSetEnd);
                        CheckArtifactBindings.ScheduleBindingsForRebind(cpc, new HashSet <ItemBinding> {
                            endProperty.Name
                        });
                    }
                }
            }
        }
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            if (!string.IsNullOrEmpty(Role)
                && !string.Equals(End.Role.Value, Role, StringComparison.Ordinal))
            {
                // TODO:  should this command be enqueued in the command processor?
                RenameCommand c = new EntityDesignRenameCommand(End, Role, true);
                CommandProcessor.InvokeSingleCommand(cpc, c);

                // bug 563525: we need to update EndProperties within AssociationSetMappings if the AssociationEnd changes.
                // we update the "Role" of an AssociationSetEnd in the RenameCommand but the SingleItemBinding that we have to update
                // that is bound to the AssociationSetEnd is unique to this situation; it is not technically a "refactor rename".
                var associationSetEnd = End.GetAntiDependenciesOfType<AssociationSetEnd>().FirstOrDefault();

                if (associationSetEnd != null)
                {
                    // we need to renormalize the associationSetEnd, since the role name will have changed.
                    XmlModelHelper.NormalizeAndResolve(associationSetEnd);

                    var endPropertiesInAssocSetMappings = associationSetEnd.GetAntiDependenciesOfType<EndProperty>();
                    foreach (var endProperty in endPropertiesInAssocSetMappings)
                    {
                        endProperty.Name.SetRefName(associationSetEnd);
                        CheckArtifactBindings.ScheduleBindingsForRebind(cpc, new HashSet<ItemBinding> { endProperty.Name });
                    }
                }
            }
        }
        internal override void Invoke(CommandProcessorContext cpc)
        {
            var viewModel = _entityType.GetRootViewModel();
            Debug.Assert(viewModel != null, "Unable to find root view model from entity type: " + _entityType.Name);

            if (viewModel != null)
            {
                var entityType = viewModel.ModelXRef.GetExisting(_entityType) as Model.Entity.EntityType;
                Debug.Assert(entityType != null);
                Command c = new EntityDesignRenameCommand(entityType, _entityType.Name, true);
                var cp = new CommandProcessor(cpc, c);
                cp.Invoke();
            }
        }
        internal override void Invoke(CommandProcessorContext cpc)
        {
            var viewModel = _property.GetRootViewModel();
            Debug.Assert(viewModel != null, "Unable to find root view model from property: " + _property.Name);

            if (viewModel != null)
            {
                var property = viewModel.ModelXRef.GetExisting(_property) as Model.Entity.Property;
                Debug.Assert(property != null);

                Command c = new EntityDesignRenameCommand(property, _property.Name, true);
                var cp = new CommandProcessor(cpc, c);
                cp.Invoke();
            }
        }
Beispiel #5
0
        private void RenameEntitySet(CommandProcessorContext cpc)
        {
            var entity = Element as EntityType;

            Debug.Assert(entity != null, "Element for rename was not EntityType");

            // rename EntitySet only if the entity has no base type
            if (entity != null)
            {
                var cet = entity as ConceptualEntityType;
                if (cet != null &&
                    cet.HasResolvableBaseType)
                {
                    return;
                }
            }

            if (entity.EntitySet != null)
            {
                var entitySetName = entity.EntitySet.LocalName.Value;

                // check if EntitySet name is of auto-generated form (which differs depending on
                // the setting of the pluralization flag)
                var autoEntitySetName = ModelHelper.ConstructProposedEntitySetName(entity.Artifact, entity.LocalName.Value);
                if (entitySetName.StartsWith(autoEntitySetName, StringComparison.CurrentCulture))
                {
                    // the actual EntitySet name may differ from the auto-generated name by an integer suffix
                    // if there were clashes with existing EntitySet names - so check this here
                    var suffix = entitySetName.Substring(autoEntitySetName.Length);
                    int i;
                    if (suffix.Length == 0 ||
                        int.TryParse(suffix, out i))
                    {
                        var proposedEntitySetName = ModelHelper.ConstructProposedEntitySetName(entity.Artifact, NewName);
                        var newEntitySetName      = ModelHelper.GetUniqueName(
                            typeof(EntitySet), (entity.EntityModel.EntityContainer), proposedEntitySetName);
                        RenameCommand cmd = new EntityDesignRenameCommand(entity.EntitySet, newEntitySetName, UniquenessIsCaseSensitive);
                        CommandProcessor.InvokeSingleCommand(cpc, cmd);
                    }
                }
            }
        }
        protected override void OnApplyChanges()
        {
            // SCCI operation, check out any file that need to be changed.
            // If failed to check out any file or user cancelled check out, return.
            var filesToCheckOut = new List<String>(GetListOfFilesToCheckOut());
            if (!EnsureFileCheckOut(filesToCheckOut))
            {
                return;
            }

            // Set up linked undo
            var linkedUndoManager = ServiceProvider.GetService(typeof(SVsLinkedUndoTransactionManager)) as IVsLinkedUndoTransactionManager;

            var completedLinkedUndo = false;
            try
            {
                var hr = linkedUndoManager.OpenLinkedUndo(ApplyChangesUndoScope, UndoDescription);
                if (hr == VSConstants.S_OK)
                {
                    var linkedUndoHr = 0;

                    // Remember what are invisible editors we open, we will release them explicitly
                    // after apply changes are done.
                    var invisibleEditors = new List<IVsInvisibleEditor>();
                    try
                    {
                        var changeCount = FileChanges.Count;
                        string errorMessage = null;
                        string fileName = null;
                        try
                        {
                            for (var changeIndex = 0; changeIndex < changeCount && !IsCancelled && !ErrorOccurred; changeIndex++)
                            {
                                var fileChange = FileChanges[changeIndex];
                                if (fileChange.IsFileModified)
                                {
                                    // When apply change to a file, if that file is not in RDT, it will open that file in invisible editor.
                                    fileName = fileChange.FileName;
                                    var textBuffer = GetTextBufferForFile(fileName, invisibleEditors);
                                    if (textBuffer != null)
                                    {
                                        ApplyChangesToOneFile(fileChange, textBuffer, false, null);
                                    }
                                }
                            }

                            // Execute the rename command to update the CSDL model
                            var artifact = _objectToRename.Artifact as EntityDesignArtifact;
                            Debug.Assert(artifact != null, "Object being refactored does not have an EntityDesignArtifact parent.");
                            if (artifact != null)
                            {
                                var renameCommand = new EntityDesignRenameCommand(_objectToRename, _newName, false);
                                var cpc = new CommandProcessorContext(
                                    artifact.EditingContext, "EFRefactoringOperation->OnApplyChanges", Resources.Tx_RefactorRenameCommand);
                                CommandProcessor.InvokeSingleCommand(cpc, renameCommand);
                            }
                        }
                        catch (IOException)
                        {
                            errorMessage = string.Format(CultureInfo.CurrentCulture, Resources.Error_FailedApplyChangeToFile, fileName);
                        }
                        catch (InvalidOperationException)
                        {
                            errorMessage = string.Format(CultureInfo.CurrentCulture, Resources.Error_FailedApplyChangeToFile, fileName);
                        }

                        if (errorMessage != null)
                        {
                            // Any error occur, abort the transaction.
                            linkedUndoManager.AbortLinkedUndo();
                            OnError(errorMessage);
                        }
                        else
                        {
                            // Succeed, close linked undo and submit the transaction.
                            // This operation will automatically save any dirty file.
                            linkedUndoHr = linkedUndoManager.CloseLinkedUndo();
                            if (linkedUndoHr != VSConstants.S_OK)
                            {
                                linkedUndoManager.AbortLinkedUndo();
                            }
                        }

                        completedLinkedUndo = true;
                    }
                    finally
                    {
                        var editorCount = invisibleEditors.Count;
                        for (var editorIndex = 0; editorIndex < editorCount; editorIndex++)
                        {
                            // Close invisible editor from RDT
                            var invisibleEditor = invisibleEditors[editorIndex];
                            if (invisibleEditor != null)
                            {
                                Marshal.ReleaseComObject(invisibleEditor);
                            }
                        }
                    }
                }
                else
                {
                    OnError(string.Format(CultureInfo.CurrentCulture, Resources.Error_FailedApplyChangeToFile, string.Empty));
                }
            }
            finally
            {
                if (completedLinkedUndo == false)
                {
                    linkedUndoManager.AbortLinkedUndo();
                }
            }
        }
        public void Simple_Association()
        {
            UITestRunner.Execute(TestContext.TestName, 
                () =>
                    {
                        const string typePrefix = "Simple_Association";
                        const string testName = "UndoRedo." + typePrefix;

                        ExecuteUndoRedoTest(
                            testName, "BlankModel.edmx", (commandProcessorContext, artifact) =>
                                {
                                    const string entity1TypeName = typePrefix + "_EntityType1";
                                    const string entity2TypeName = typePrefix + "_EntityType2";
                                    const string association1TypeName = typePrefix + "_Association1";
                                    const string association2TypeName = typePrefix + "_Association2";

                                    var dte = VsIdeTestHostContext.Dte;

                                    // Note: we cannot populate these EFObjects as soon as we create them. Since we are undoing/redoing, 
                                    // we will create new instances and need to discover them "on-demand"
                                    ConceptualEntityType entityType1;
                                    ConceptualEntityType entityType2;

                                    // CREATE TWO ENTITIES
                                    CreateDefaultEntityType(commandProcessorContext, entity1TypeName, typePrefix + "_EntitySet1");
                                    CreateDefaultEntityType(commandProcessorContext, entity2TypeName, typePrefix + "_EntitySet2");

                                    entityType1 = artifact.GetFreshConceptualEntity(entity1TypeName);
                                    entityType2 = artifact.GetFreshConceptualEntity(entity2TypeName);

                                    Assert.IsNotNull(entityType1);
                                    Assert.IsNotNull(entityType2);

                                    // CREATE ASSOCIATION
                                    new CommandProcessor(
                                        commandProcessorContext,
                                        new CreateConceptualAssociationCommand(
                                            association1TypeName,
                                            entityType1, "*", "Entity2",
                                            entityType2, "1", "Entity1",
                                            uniquifyNames: false,
                                            createForeignKeyProperties: false)).Invoke();

                                    Assert.IsNotNull(artifact.GetFreshAssociation(association1TypeName), "Association not created.");

                                    // Undo Redo "Create Association1"
                                    dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), UndoCommand);
                                    Assert.IsNull(artifact.GetFreshAssociation(association1TypeName));
                                    dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), RedoCommand);

                                    Assert.IsNotNull(
                                        artifact.GetFreshAssociation(association1TypeName), "Association should not have disappeared.");

                                    // DELETE ASSOCIATION
                                    new CommandProcessor(
                                        commandProcessorContext,
                                        artifact.GetFreshAssociation(association1TypeName).GetDeleteCommand()).Invoke();
                                    Assert.AreEqual(0, artifact.ConceptualModel().AssociationCount, "No associations expected.");

                                    // Undo Redo "Delete Association1"
                                    dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), UndoCommand);
                                    Assert.IsNotNull(artifact.GetFreshAssociation(association1TypeName));
                                    dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), RedoCommand);
                                    Assert.AreEqual(0, artifact.ConceptualModel().AssociationCount, "No associations expected.");

                                    // Undo "Delete Association1"
                                    dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), UndoCommand);
                                    Assert.IsNotNull(
                                        artifact.GetFreshAssociation(association1TypeName), "Association not re-created after Undo.");

                                    // CREATE ANOTHER ASSOCIATION 2 (we'll make it a self-association for good measure)
                                    entityType1 = artifact.GetFreshConceptualEntity(entity1TypeName);
                                    entityType2 = artifact.GetFreshConceptualEntity(entity1TypeName);
                                    new CommandProcessor(
                                        commandProcessorContext,
                                        new CreateConceptualAssociationCommand(
                                            association2TypeName,
                                            entityType1, "*", "Entity1_1",
                                            entityType1, "1", "Entity1_2",
                                            uniquifyNames: false,
                                            createForeignKeyProperties: false)).Invoke();
                                    Assert.IsNotNull(artifact.GetFreshAssociation(association2TypeName), "Association not created.");

                                    // Undo Redo "Create Association2"
                                    dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), UndoCommand);
                                    Assert.IsNull(artifact.GetFreshAssociation(association2TypeName));
                                    dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), RedoCommand);
                                    Assert.IsNotNull(
                                        artifact.GetFreshAssociation(association2TypeName), "Association should not have disappeared.");

                                    // CHANGE MULTIPLICITY
                                    var association1End1 = artifact.GetFreshAssociationEnd(association1TypeName, 0);
                                    Assert.AreEqual("*", association1End1.Multiplicity.Value);
                                    new CommandProcessor(
                                        commandProcessorContext,
                                        new ChangeAssociationEndCommand(association1End1, "1", null)).Invoke();

                                    Assert.AreEqual("1", artifact.GetFreshAssociationEnd(association1TypeName, 0).Multiplicity.Value);

                                    //Undo Redo "Change Association1 End1 Multiplicity: * --> 1"
                                    dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), UndoCommand);
                                    Assert.AreEqual("*", artifact.GetFreshAssociationEnd(association1TypeName, 0).Multiplicity.Value);
                                    dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), RedoCommand);
                                    Assert.AreEqual("1", artifact.GetFreshAssociationEnd(association1TypeName, 0).Multiplicity.Value);

                                    // CHANGE ROLE
                                    var association2End1 = artifact.GetFreshAssociationEnd(association2TypeName, 0);
                                    Assert.AreEqual("Simple_Association_EntityType1", association2End1.Role.Value);
                                    new CommandProcessor(
                                        commandProcessorContext,
                                        new ChangeAssociationEndCommand(association2End1, association2End1.Multiplicity.Value, "Entity2"))
                                        .Invoke();
                                    Assert.AreEqual("Entity2", artifact.GetFreshAssociationEnd(association2TypeName, 0).Role.Value);

                                    // Undo Redo "Change Association2 End2 Role: Entity1 --> Entity2"
                                    dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), UndoCommand);
                                    Assert.AreEqual(
                                        "Simple_Association_EntityType1",
                                        artifact.GetFreshAssociationEnd(association2TypeName, 0).Role.Value);
                                    dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), RedoCommand);
                                    Assert.AreEqual("Entity2", artifact.GetFreshAssociationEnd(association2TypeName, 0).Role.Value);

                                    // CHANGE NAVIGATION PROPERTY NAME
                                    entityType1 = artifact.GetFreshConceptualEntity(entity1TypeName);
                                    var entityType1NavProp1 =
                                        entityType1.NavigationProperties().Single(np => np.LocalName.Value == "Entity2");
                                    new CommandProcessor(
                                        commandProcessorContext,
                                        new EntityDesignRenameCommand(entityType1NavProp1, "Entity2_1", false)).Invoke();
                                    Assert.IsNotNull(
                                        entityType1.NavigationProperties().SingleOrDefault(np => np.LocalName.Value == "Entity2_1"));

                                    // Undo Redo "Rename EntityType1 NavigationProperty1: Entity2 --> Entity2_1"
                                    dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), UndoCommand);
                                    Assert.IsNotNull(
                                        artifact.GetFreshConceptualEntity(entity1TypeName)
                                            .NavigationProperties()
                                            .SingleOrDefault(np => np.LocalName.Value == "Entity2"));
                                    dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), RedoCommand);
                                    Assert.IsNotNull(
                                        artifact.GetFreshConceptualEntity(entity1TypeName)
                                            .NavigationProperties()
                                            .SingleOrDefault(np => np.LocalName.Value == "Entity2_1"));

                                    // RENAME ENTITYSET (changes AssociationSetEnds)
                                    Assert.AreEqual(
                                        "Simple_Association_EntitySet1",
                                        artifact.GetFreshAssociation(association1TypeName).AssociationSet.AssociationSetEnds()[0].EntitySet
                                            .RefName);
                                    Assert.AreEqual(
                                        "Simple_Association_EntitySet1",
                                        artifact.GetFreshAssociation(association2TypeName).AssociationSet.AssociationSetEnds()[0].EntitySet
                                            .RefName);
                                    Assert.AreEqual(
                                        "Simple_Association_EntitySet1",
                                        artifact.GetFreshAssociation(association2TypeName).AssociationSet.AssociationSetEnds()[1].EntitySet
                                            .RefName);

                                    entityType1 = artifact.GetFreshConceptualEntity(entity1TypeName);
                                    var entityType1Set = (ConceptualEntitySet)entityType1.EntitySet;
                                    RenameCommand renameEt1set = new EntityDesignRenameCommand(entityType1Set, "Entity1Set_1", false);
                                    new CommandProcessor(
                                        commandProcessorContext,
                                        new EntityDesignRenameCommand(entityType1Set, "Entity1Set_1", false)).Invoke();
                                    Assert.AreEqual(
                                        "Entity1Set_1",
                                        artifact.GetFreshAssociation(association1TypeName).AssociationSet.AssociationSetEnds()[0].EntitySet
                                            .RefName);
                                    Assert.AreEqual(
                                        "Entity1Set_1",
                                        artifact.GetFreshAssociation(association2TypeName).AssociationSet.AssociationSetEnds()[0].EntitySet
                                            .RefName);
                                    Assert.AreEqual(
                                        "Entity1Set_1",
                                        artifact.GetFreshAssociation(association2TypeName).AssociationSet.AssociationSetEnds()[1].EntitySet
                                            .RefName);

                                    // Undo Redo"Rename EntityType1 EntitySet: Entity1Set --> Entity1Set_1"
                                    dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), UndoCommand);
                                    Assert.AreEqual(
                                        "Simple_Association_EntitySet1",
                                        artifact.GetFreshAssociation(association1TypeName).AssociationSet.AssociationSetEnds()[0].EntitySet
                                            .RefName);
                                    Assert.AreEqual(
                                        "Simple_Association_EntitySet1",
                                        artifact.GetFreshAssociation(association2TypeName).AssociationSet.AssociationSetEnds()[0].EntitySet
                                            .RefName);
                                    Assert.AreEqual(
                                        "Simple_Association_EntitySet1",
                                        artifact.GetFreshAssociation(association2TypeName).AssociationSet.AssociationSetEnds()[1].EntitySet
                                            .RefName);

                                    dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), RedoCommand);
                                    Assert.AreEqual(
                                        "Entity1Set_1",
                                        artifact.GetFreshAssociation(association1TypeName).AssociationSet.AssociationSetEnds()[0].EntitySet
                                            .RefName);
                                    Assert.AreEqual(
                                        "Entity1Set_1",
                                        artifact.GetFreshAssociation(association2TypeName).AssociationSet.AssociationSetEnds()[0].EntitySet
                                            .RefName);
                                    Assert.AreEqual(
                                        "Entity1Set_1",
                                        artifact.GetFreshAssociation(association2TypeName).AssociationSet.AssociationSetEnds()[1].EntitySet
                                            .RefName);

                                    // RENAME ASSOCIATION
                                    new CommandProcessor(
                                        commandProcessorContext,
                                        new EntityDesignRenameCommand(
                                            artifact.GetFreshAssociation(association2TypeName),
                                            "Entity1Entity1_new",
                                            false)).Invoke();
                                    Assert.IsNotNull(artifact.GetFreshAssociation("Entity1Entity1_new"));

                                    // Undo Redo "Rename Association2"
                                    dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), UndoCommand);
                                    Assert.IsNotNull(artifact.GetFreshAssociation(association2TypeName));
                                    dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), RedoCommand);
                                    Assert.IsNotNull(artifact.GetFreshAssociation("Entity1Entity1_new"));

                                    // RENAME ASSOCIATION
                                    new CommandProcessor(
                                        commandProcessorContext,
                                        new EntityDesignRenameCommand(
                                            artifact.GetFreshAssociation(association1TypeName),
                                            "Entity2Entity1_newSet",
                                            false)).Invoke();

                                    Assert.IsNull(artifact.GetFreshAssociation(association1TypeName));
                                    Assert.IsNotNull(artifact.GetFreshAssociation("Entity2Entity1_newSet"));

                                    // Undo Redo "Rename Association1 Set"
                                    dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), UndoCommand);
                                    Assert.IsNotNull(artifact.GetFreshAssociation(association1TypeName));
                                    Assert.IsNull(artifact.GetFreshAssociation("Entity2Entity1_newSet"));

                                    dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), RedoCommand);
                                    Assert.IsNull(artifact.GetFreshAssociation(association1TypeName));
                                    Assert.IsNotNull(artifact.GetFreshAssociation("Entity2Entity1_newSet"));
                                });
                    });
        }
        private void RenameEntitySet(CommandProcessorContext cpc)
        {
            var entity = Element as EntityType;
            Debug.Assert(entity != null, "Element for rename was not EntityType");

            // rename EntitySet only if the entity has no base type
            if (entity != null)
            {
                var cet = entity as ConceptualEntityType;
                if (cet != null
                    && cet.HasResolvableBaseType)
                {
                    return;
                }
            }

            if (entity.EntitySet != null)
            {
                var entitySetName = entity.EntitySet.LocalName.Value;

                // check if EntitySet name is of auto-generated form (which differs depending on 
                // the setting of the pluralization flag)                    
                var autoEntitySetName = ModelHelper.ConstructProposedEntitySetName(entity.Artifact, entity.LocalName.Value);
                if (entitySetName.StartsWith(autoEntitySetName, StringComparison.CurrentCulture))
                {
                    // the actual EntitySet name may differ from the auto-generated name by an integer suffix
                    // if there were clashes with existing EntitySet names - so check this here
                    var suffix = entitySetName.Substring(autoEntitySetName.Length);
                    int i;
                    if (suffix.Length == 0
                        || int.TryParse(suffix, out i))
                    {
                        var proposedEntitySetName = ModelHelper.ConstructProposedEntitySetName(entity.Artifact, NewName);
                        var newEntitySetName = ModelHelper.GetUniqueName(
                            typeof(EntitySet), (entity.EntityModel.EntityContainer), proposedEntitySetName);
                        RenameCommand cmd = new EntityDesignRenameCommand(entity.EntitySet, newEntitySetName, UniquenessIsCaseSensitive);
                        CommandProcessor.InvokeSingleCommand(cpc, cmd);
                    }
                }
            }
        }