protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            var cp = new CommandProcessor(cpc);
            CreateFunctionComplexPropertyCommand preReqCmd = null;

            for (var i = 0; i < _propertyChain.Count; i++)
            {
                var property = _propertyChain[i];
                Debug.Assert(property.EntityModel.IsCSDL, "Each Property in the chain must be in the CSDL");
                var complexConceptualProperty = property as ComplexConceptualProperty;
                if (complexConceptualProperty != null)
                {
                    Debug.Assert(i < _propertyChain.Count - 1, "Last property shouldn't be ComplexConceptualProperty");
                    CreateFunctionComplexPropertyCommand cmd = null;
                    if (preReqCmd == null)
                    {
                        // first property has a mapping whose parent is the ModificationFunction itself
                        cmd = new CreateFunctionComplexPropertyCommand(_modificationFunction, complexConceptualProperty);
                    }
                    else
                    {
                        // later properties have a mapping whose parent is the ComplexProperty produced from the previous command
                        cmd = new CreateFunctionComplexPropertyCommand(preReqCmd, complexConceptualProperty);
                    }

                    // set up the prereq Command to use for next time around this loop and for the
                    // CreateFunctionScalarPropertyCommand below
                    preReqCmd = cmd;

                    // enqueue the command
                    cp.EnqueueCommand(cmd);
                }
                else
                {
                    Debug.Assert(i == _propertyChain.Count - 1, "This should be the last property");

                    CreateFunctionScalarPropertyCommand cmd = null;
                    if (preReqCmd == null)
                    {
                        // create the FunctionScalarProperty command without any other properties in the property chain
                        cmd = new CreateFunctionScalarPropertyCommand(
                            _modificationFunction, property, _navPropPointingToProperty, _parameter, _version);
                    }
                    else
                    {
                        // create the FunctionScalarProperty command using the command for the previous property in the property chain
                        cmd = new CreateFunctionScalarPropertyCommand(preReqCmd, property, _navPropPointingToProperty, _parameter, _version);
                    }

                    cp.EnqueueCommand(cmd);
                    cp.Invoke();
                    _createdProperty = cmd.FunctionScalarProperty;
                    if (_createdProperty != null)
                    {
                        XmlModelHelper.NormalizeAndResolve(_createdProperty);
                    }
                    return;
                }
            }
        }
        /// <summary>
        ///     This helper function is an easy way to get a new entity type, entity set and key property in the
        ///     new entity type created in the conceptual or storage model.
        ///     NOTE: If the cpc already has an active transaction, these changes will be in that transaction
        ///     and the caller of this helper method must commit it to see these changes commited.
        /// </summary>
        /// <param name="cpc"></param>
        /// <param name="name">The name of the new entity</param>
        /// <param name="setName">The name of the new set</param>
        /// <param name="createKeyProperty">A flag whether to create a new key property or not (sending false creates no new property)</param>
        /// <param name="propertyName">The name of the new property</param>
        /// <param name="propertyType">The type of the new property</param>
        /// <param name="modelSpace">Either Conceptual or Storage</param>
        /// <param name="uniquifyName">Flag whether the name should be checked for uniqueness and then changed as required</param>
        /// <param name="isDefaultName">Flag whether the name is the default for new entity types/sets</param>
        /// <returns>The new EntityType</returns>
        internal static EntityType CreateEntityTypeAndEntitySetAndProperty(
            CommandProcessorContext cpc,
            string name, string setName, bool createKeyProperty, string propertyName,
            string propertyType, string propertyStoreGeneratedPattern, ModelSpace modelSpace, bool uniquifyNames, bool isDefaultName = false)
        {
            var cp = new CommandProcessor(cpc);

            var cet = new CreateEntityTypeCommand(name, modelSpace, uniquifyNames);

            cet.CreateWithDefaultName = isDefaultName;
            cp.EnqueueCommand(cet);

            var ces = new CreateEntitySetCommand(setName, cet, modelSpace, uniquifyNames);

            cp.EnqueueCommand(ces);

            if (createKeyProperty)
            {
                var cpcd = new CreatePropertyCommand(propertyName, cet, propertyType, false);
                cpcd.IsIdProperty = true;
                cp.EnqueueCommand(cpcd);

                var skpc = new SetKeyPropertyCommand(cpcd, true);
                cp.EnqueueCommand(skpc);

                var ssgpc = new SetStoreGeneratedPatternCommand(cpcd, propertyStoreGeneratedPattern);
                cp.EnqueueCommand(ssgpc);
            }

            cp.Invoke();

            return(cet.EntityType);
        }
        internal static void StaticInvoke(CommandProcessorContext cpc, EntityTypeShape entityTypeShape, Guid domainPropertyId)
        {
            var viewModel = entityTypeShape.GetRootViewModel();
            Debug.Assert(viewModel != null, "Unable to find root view model from entity type shape:" + entityTypeShape.AccessibleName);

            if (viewModel != null)
            {
                var modelEntityShape = viewModel.ModelXRef.GetExisting(entityTypeShape) as Model.Designer.EntityTypeShape;

                // If ModelXRef does not contain about model EntityTypeShape,try to get the information through DSL Model Element
                if (modelEntityShape == null)
                {
                    var modelDiagram = viewModel.ModelXRef.GetExisting(viewModel.GetDiagram()) as Diagram;
                    var entityType = viewModel.ModelXRef.GetExisting(entityTypeShape.ModelElement) as EntityType;
                    Debug.Assert(modelDiagram != null, "Why Escher Diagram is null?");
                    Debug.Assert(entityType != null, "Why there is no XRef between Escher EntityType and DSL EntityT?");
                    if (modelDiagram != null
                        && entityType != null)
                    {
                        modelEntityShape =
                            entityType.GetAntiDependenciesOfType<Model.Designer.EntityTypeShape>()
                            .FirstOrDefault(ets => ets.Diagram.Id == modelDiagram.Id.Value);
                    }

                    if (modelEntityShape != null)
                    {
                        viewModel.ModelXRef.Add(modelEntityShape, entityTypeShape, cpc.EditingContext);
                    }
                }

                // if modelentityshape is still null, create one
                if (modelEntityShape == null)
                {
                    EntityTypeShapeAdd.StaticInvoke(cpc, entityTypeShape);
                    modelEntityShape = viewModel.ModelXRef.GetExisting(entityTypeShape) as Model.Designer.EntityTypeShape;
                }
                Debug.Assert(modelEntityShape != null);
                if (modelEntityShape != null)
                {
                    if (domainPropertyId == NodeShape.AbsoluteBoundsDomainPropertyId)
                    {
                        var cp = new CommandProcessor(cpc);
                        cp.EnqueueCommand(
                            new UpdateDefaultableValueCommand<double>(modelEntityShape.PointX, entityTypeShape.AbsoluteBounds.X));
                        cp.EnqueueCommand(
                            new UpdateDefaultableValueCommand<double>(modelEntityShape.PointY, entityTypeShape.AbsoluteBounds.Y));
                        cp.EnqueueCommand(
                            new UpdateDefaultableValueCommand<double>(modelEntityShape.Width, entityTypeShape.AbsoluteBounds.Width));
                        cp.Invoke();
                    }
                    else if (domainPropertyId == NodeShape.IsExpandedDomainPropertyId)
                    {
                        var cmd = new UpdateDefaultableValueCommand<bool>(modelEntityShape.IsExpanded, entityTypeShape.IsExpanded);
                        CommandProcessor.InvokeSingleCommand(cpc, cmd);
                    }
                }
            }
        }
        public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
        {
            if (context == null
                || context.Instance == null)
            {
                return value;
            }

            var desc = context.Instance as EFAssociationDescriptor;
            if (desc != null)
            {
                var assoc = desc.WrappedItem as Association;

                if (assoc != null)
                {
                    var commands = ReferentialConstraintDialog.LaunchReferentialConstraintDialog(assoc);
                    var cpc = new CommandProcessorContext(
                        desc.EditingContext,
                        EfiTransactionOriginator.PropertyWindowOriginatorId,
                        Resources.Tx_ReferentialContraint);
                    var cp = new CommandProcessor(cpc);
                    foreach (var c in commands)
                    {
                        cp.EnqueueCommand(c);
                    }
                    cp.Invoke();
                }
            }

            return value;
        }
        /// <summary>
        ///     This helper function will create a Diagram using default name.
        ///     NOTE: If the cpc already has an active transaction, these changes will be in that transaction
        ///     and the caller of this helper method must commit it to see these changes commited
        ///     otherwise the diagram will never be created.
        /// </summary>
        /// <param name="cpc"></param>
        /// <returns>The new ComplexType</returns>
        internal static Diagram CreateDiagramWithDefaultName(CommandProcessorContext cpc)
        {
            Debug.Assert(cpc != null, "The passed in CommandProcessorContext is null.");
            if (cpc != null)
            {
                var service = cpc.EditingContext.GetEFArtifactService();
                var entityDesignArtifact = service.Artifact as EntityDesignArtifact;

                if (entityDesignArtifact == null
                    || entityDesignArtifact.DesignerInfo == null
                    || entityDesignArtifact.DesignerInfo.Diagrams == null)
                {
                    throw new CannotLocateParentItemException();
                }

                var diagramName = ModelHelper.GetUniqueNameWithNumber(
                    typeof(Diagram), entityDesignArtifact.DesignerInfo.Diagrams, Resources.Model_DefaultDiagramName);

                // go create it
                var cp = new CommandProcessor(cpc);
                var cmd = new CreateDiagramCommand(diagramName, entityDesignArtifact.DesignerInfo.Diagrams);
                cp.EnqueueCommand(cmd);
                cp.Invoke();
                return cmd.Diagram;
            }
            return null;
        }
Exemple #6
0
        /// <summary>
        ///     This helper function will create a Diagram using default name.
        ///     NOTE: If the cpc already has an active transaction, these changes will be in that transaction
        ///     and the caller of this helper method must commit it to see these changes commited
        ///     otherwise the diagram will never be created.
        /// </summary>
        /// <param name="cpc"></param>
        /// <returns>The new ComplexType</returns>
        internal static Diagram CreateDiagramWithDefaultName(CommandProcessorContext cpc)
        {
            Debug.Assert(cpc != null, "The passed in CommandProcessorContext is null.");
            if (cpc != null)
            {
                var service = cpc.EditingContext.GetEFArtifactService();
                var entityDesignArtifact = service.Artifact as EntityDesignArtifact;

                if (entityDesignArtifact == null ||
                    entityDesignArtifact.DesignerInfo == null ||
                    entityDesignArtifact.DesignerInfo.Diagrams == null)
                {
                    throw new CannotLocateParentItemException();
                }

                var diagramName = ModelHelper.GetUniqueNameWithNumber(
                    typeof(Diagram), entityDesignArtifact.DesignerInfo.Diagrams, Resources.Model_DefaultDiagramName);

                // go create it
                var cp  = new CommandProcessor(cpc);
                var cmd = new CreateDiagramCommand(diagramName, entityDesignArtifact.DesignerInfo.Diagrams);
                cp.EnqueueCommand(cmd);
                cp.Invoke();
                return(cmd.Diagram);
            }
            return(null);
        }
        internal static bool SetBaseEntityType(
            CommandProcessorContext cpc, ConceptualEntityType derivedEntity, ConceptualEntityType baseEntity)
        {
            if (ModelHelper.CheckForCircularInheritance(derivedEntity, baseEntity))
            {
                var message = String.Format(
                    CultureInfo.CurrentCulture, Resources.Error_CircularInheritanceAborted, derivedEntity.LocalName.Value,
                    baseEntity.LocalName.Value);

                VsUtils.ShowErrorDialog(message);

                return false;
            }

            var cp = new CommandProcessor(cpc);

            if (derivedEntity.BaseType.Target != null)
            {
                // CreateInheritanceCommand works only for entities that don't have base type set
                // so we need to remove base type first in this case
                cp.EnqueueCommand(new DeleteInheritanceCommand(derivedEntity));
            }

            if (baseEntity != null)
            {
                // in case the user has chosen "(None)" then we just want to delete the existing one
                cp.EnqueueCommand(new CreateInheritanceCommand(derivedEntity, baseEntity));
            }

            // a quick check to be sure
            Debug.Assert(cp.CommandCount > 0, "Why didn't we enqueue at least one command?");
            if (cp.CommandCount > 0)
            {
                cp.Invoke();
            }

            return true;
        }
        /// <summary>
        ///     This helper function will create a complex type using default name.
        ///     NOTE: If the cpc already has an active transaction, these changes will be in that transaction
        ///     and the caller of this helper method must commit it to see these changes committed.
        /// </summary>
        /// <param name="cpc"></param>
        /// <returns>The new ComplexType</returns>
        internal static ComplexType CreateComplexTypeWithDefaultName(CommandProcessorContext cpc)
        {
            var service  = cpc.EditingContext.GetEFArtifactService();
            var artifact = service.Artifact;

            // the model that we want to add the complex type to
            var model = artifact.ConceptualModel();

            if (model == null)
            {
                throw new CannotLocateParentItemException();
            }

            var complexTypeName = ModelHelper.GetUniqueNameWithNumber(typeof(ComplexType), model, Resources.Model_DefaultComplexTypeName);

            // go create it
            var cp  = new CommandProcessor(cpc);
            var cmd = new CreateComplexTypeCommand(complexTypeName, false);

            cp.EnqueueCommand(cmd);
            cp.Invoke();
            return(cmd.ComplexType);
        }
        internal void AddMissingAssociationConnectors(EntityDesignArtifact efArtifact, out bool addedMissingShapes)
        {
            addedMissingShapes = false;
            Debug.Assert(efArtifact != null, "EFArtifact is null");
            if (efArtifact != null)
            {
                // Now, for all associations, ensure that an association connector is created.
                var dslDiagram = Diagram as EntityDesignerDiagram;
                if (efArtifact.ConceptualModel() != null
                    && dslDiagram != null)
                {
                    var associationsMaterializedAsConnectors = new HashSet<ModelAssociation>();
                    foreach (
                        var connector in
                            efArtifact.DesignerInfo.Diagrams.Items.Where(d => d.Id.Value == DiagramId)
                                .SelectMany(d => d.AssociationConnectors))
                    {
                        // First check if there's a ModelElement for this.
                        var associationConnector = dslDiagram.ModelElement.ModelXRef.GetExisting(connector) as AssociationConnector;
                        if (associationConnector != null
                            && connector.Association.Target != null
                            && !associationsMaterializedAsConnectors.Contains(connector.Association.Target))
                        {
                            associationsMaterializedAsConnectors.Add(connector.Association.Target);
                        }
                    }

                    var cpc = new CommandProcessorContext(
                        efArtifact.EditingContext,
                        EfiTransactionOriginator.EntityDesignerOriginatorId,
                        "Restore Excluded Elements");
                    var cp = new CommandProcessor(cpc, shouldNotifyObservers: true);

                    foreach (var association in efArtifact.ConceptualModel().Associations())
                    {
                        if (!associationsMaterializedAsConnectors.Contains(association))
                        {
                            var shouldAddConnector = true;
                            var entityTypesOnEnds = association.AssociationEnds().Select(ae => ae.Type.Target);
                            foreach (var entityType in entityTypesOnEnds)
                            {
                                if (entityType != null
                                    && entityType.GetAntiDependenciesOfType<Model.Designer.EntityTypeShape>()
                                           .Any(ets => ets.Diagram.Id == DiagramId) == false)
                                {
                                    shouldAddConnector = false;
                                    break;
                                }
                            }

                            if (shouldAddConnector)
                            {
                                var modelDiagram = dslDiagram.ModelElement.ModelXRef.GetExisting(dslDiagram) as ModelDiagram;
                                if (modelDiagram != null)
                                {
                                    cp.EnqueueCommand(new CreateAssociationConnectorCommand(modelDiagram, association));
                                }
                            }
                        }
                    }

                    if (cp.CommandCount > 0)
                    {
                        cp.Invoke();
                        addedMissingShapes = true;
                    }
                }
            }
        }
        /// <summary>
        ///     This helper function is an easy way to get a new entity type, entity set and key property in the
        ///     new entity type created in the conceptual or storage model.
        ///     NOTE: If the cpc already has an active transaction, these changes will be in that transaction
        ///     and the caller of this helper method must commit it to see these changes commited.
        /// </summary>
        /// <param name="cpc"></param>
        /// <param name="name">The name of the new entity</param>
        /// <param name="setName">The name of the new set</param>
        /// <param name="createKeyProperty">A flag whether to create a new key property or not (sending false creates no new property)</param>
        /// <param name="propertyName">The name of the new property</param>
        /// <param name="propertyType">The type of the new property</param>
        /// <param name="modelSpace">Either Conceptual or Storage</param>
        /// <param name="uniquifyName">Flag whether the name should be checked for uniqueness and then changed as required</param>
        /// <param name="isDefaultName">Flag whether the name is the default for new entity types/sets</param>
        /// <returns>The new EntityType</returns>
        internal static EntityType CreateEntityTypeAndEntitySetAndProperty(
            CommandProcessorContext cpc,
            string name, string setName, bool createKeyProperty, string propertyName,
            string propertyType, string propertyStoreGeneratedPattern, ModelSpace modelSpace, bool uniquifyNames, bool isDefaultName = false)
        {
            var cp = new CommandProcessor(cpc);

            var cet = new CreateEntityTypeCommand(name, modelSpace, uniquifyNames);
            cet.CreateWithDefaultName = isDefaultName;
            cp.EnqueueCommand(cet);

            var ces = new CreateEntitySetCommand(setName, cet, modelSpace, uniquifyNames);
            cp.EnqueueCommand(ces);

            if (createKeyProperty)
            {
                var cpcd = new CreatePropertyCommand(propertyName, cet, propertyType, false);
                cpcd.IsIdProperty = true;
                cp.EnqueueCommand(cpcd);

                var skpc = new SetKeyPropertyCommand(cpcd, true);
                cp.EnqueueCommand(skpc);

                var ssgpc = new SetStoreGeneratedPatternCommand(cpcd, propertyStoreGeneratedPattern);
                cp.EnqueueCommand(ssgpc);
            }

            cp.Invoke();

            return cet.EntityType;
        }
        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);
                        }
                    }
                }
            }
        }
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            var cp = new CommandProcessor(cpc);
            CreateFunctionComplexPropertyCommand preReqCmd = null;
            for (var i = 0; i < _propertyChain.Count; i++)
            {
                var property = _propertyChain[i];
                Debug.Assert(property.EntityModel.IsCSDL, "Each Property in the chain must be in the CSDL");
                var complexConceptualProperty = property as ComplexConceptualProperty;
                if (complexConceptualProperty != null)
                {
                    Debug.Assert(i < _propertyChain.Count - 1, "Last property shouldn't be ComplexConceptualProperty");
                    CreateFunctionComplexPropertyCommand cmd = null;
                    if (preReqCmd == null)
                    {
                        // first property has a mapping whose parent is the ModificationFunction itself
                        cmd = new CreateFunctionComplexPropertyCommand(_modificationFunction, complexConceptualProperty);
                    }
                    else
                    {
                        // later properties have a mapping whose parent is the ComplexProperty produced from the previous command
                        cmd = new CreateFunctionComplexPropertyCommand(preReqCmd, complexConceptualProperty);
                    }

                    // set up the prereq Command to use for next time around this loop and for the 
                    // CreateFunctionScalarPropertyCommand below
                    preReqCmd = cmd;

                    // enqueue the command
                    cp.EnqueueCommand(cmd);
                }
                else
                {
                    Debug.Assert(i == _propertyChain.Count - 1, "This should be the last property");

                    CreateFunctionScalarPropertyCommand cmd = null;
                    if (preReqCmd == null)
                    {
                        // create the FunctionScalarProperty command without any other properties in the property chain
                        cmd = new CreateFunctionScalarPropertyCommand(
                            _modificationFunction, property, _navPropPointingToProperty, _parameter, _version);
                    }
                    else
                    {
                        // create the FunctionScalarProperty command using the command for the previous property in the property chain
                        cmd = new CreateFunctionScalarPropertyCommand(preReqCmd, property, _navPropPointingToProperty, _parameter, _version);
                    }

                    cp.EnqueueCommand(cmd);
                    cp.Invoke();
                    _createdProperty = cmd.FunctionScalarProperty;
                    if (_createdProperty != null)
                    {
                        XmlModelHelper.NormalizeAndResolve(_createdProperty);
                    }
                    return;
                }
            }
        }
        // <summary>
        //     Show the dialog to create a new enum type.
        // </summary>
        public static EnumType AddNewEnumType(
            string selectedUnderlyingType, EditingContext editingContext, string originatingId, EventHandler onDialogActivated = null)
        {
            if (editingContext == null)
            {
                throw new ArgumentNullException("editingContext");
            }

            var artifactService = editingContext.GetEFArtifactService();
            var entityDesignArtifact = artifactService.Artifact as EntityDesignArtifact;

            Debug.Assert(
                entityDesignArtifact != null,
                typeof(EntityDesignViewModelHelper).Name
                + ".AddEnumType: Unable to find Entity Design Artifact from the passed in editing context.");

            if (entityDesignArtifact != null)
            {
                var vm = new EnumTypeViewModel(entityDesignArtifact, selectedUnderlyingType);

                var result = ShowEnumTypeDialog(vm, onDialogActivated);

                if (result == true
                    && vm.IsValid)
                {
                    var cp = new CommandProcessor(editingContext, originatingId, Resources.Tx_CreateEnumType);
                    var createEnumTypeCommand = new CreateEnumTypeCommand(
                        vm.Name, vm.SelectedUnderlyingType
                        , (vm.IsReferenceExternalType ? vm.ExternalTypeName : String.Empty), vm.IsFlag, false);

                    cp.EnqueueCommand(createEnumTypeCommand);

                    foreach (var member in vm.Members)
                    {
                        if (String.IsNullOrWhiteSpace(member.Name) == false)
                        {
                            cp.EnqueueCommand(new CreateEnumTypeMemberCommand(createEnumTypeCommand, member.Name, member.Value));
                        }
                    }
                    cp.Invoke();
                    return createEnumTypeCommand.EnumType;
                }
            }
            return null;
        }
        internal void AddMissingEntityTypeShapes(EntityDesignArtifact efArtifact, out bool addedMissingShapes)
        {
            addedMissingShapes = false;
            Debug.Assert(efArtifact != null, "EFArtifact is null");
            if (efArtifact != null)
            {
                // Now, for all entitytypes, ensure that an entitytype shape is created.
                var dslDiagram = Diagram as EntityDesignerDiagram;
                if (efArtifact.ConceptualModel() != null
                    && dslDiagram != null)
                {
                    var entityTypesMaterializedAsShapes = new HashSet<Model.Entity.EntityType>();
                    foreach (
                        var designerEntityTypeShape in
                            efArtifact.DesignerInfo.Diagrams.Items.Where(d => d.Id.Value == DiagramId).SelectMany(d => d.EntityTypeShapes))
                    {
                        // First check if there's a ModelElement for this.
                        var entityTypeShape = dslDiagram.ModelElement.ModelXRef.GetExisting(designerEntityTypeShape) as EntityTypeShape;
                        if (entityTypeShape != null
                            && designerEntityTypeShape.EntityType.Target != null
                            && !entityTypesMaterializedAsShapes.Contains(designerEntityTypeShape.EntityType.Target))
                        {
                            entityTypesMaterializedAsShapes.Add(designerEntityTypeShape.EntityType.Target);
                        }
                    }

                    var cpc = new CommandProcessorContext(
                        efArtifact.EditingContext,
                        EfiTransactionOriginator.EntityDesignerOriginatorId,
                        "Restore Excluded Elements");
                    var cp = new CommandProcessor(cpc, shouldNotifyObservers: true);

                    foreach (var entityType in efArtifact.ConceptualModel().EntityTypes())
                    {
                        if (!entityTypesMaterializedAsShapes.Contains(entityType))
                        {
                            var modelDiagram = dslDiagram.ModelElement.ModelXRef.GetExisting(dslDiagram) as ModelDiagram;
                            if (modelDiagram != null)
                            {
                                cp.EnqueueCommand(new CreateEntityTypeShapeCommand(modelDiagram, entityType));
                            }
                        }
                    }

                    if (cp.CommandCount > 0)
                    {
                        cp.Invoke();
                        addedMissingShapes = true;
                    }
                }
            }
        }
Exemple #15
0
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            Debug.Assert(
                _mode == Mode.EntityType || _mode == Mode.MappingFragment, "Unknown mode set in CreateFragmentScalarPropertyTreeCommand");

            var cp = new CommandProcessor(cpc);
            CreateFragmentComplexPropertyCommand prereqCmd = null;

            for (var i = 0; i < _properties.Count; i++)
            {
                var property = _properties[i];
                var complexConceptualProperty = property as ComplexConceptualProperty;
                if (complexConceptualProperty != null)
                {
                    Debug.Assert(i < _properties.Count - 1, "Last property shouldn't be ComplexConceptualProperty");
                    CreateFragmentComplexPropertyCommand cmd = null;
                    if (prereqCmd == null)
                    {
                        if (_mode == Mode.EntityType)
                        {
                            cmd = new CreateFragmentComplexPropertyCommand(_conceptualEntityType, complexConceptualProperty, _tableColumn);
                        }
                        else
                        {
                            cmd = new CreateFragmentComplexPropertyCommand(_mappingFragment, complexConceptualProperty);
                        }
                    }
                    else
                    {
                        cmd = new CreateFragmentComplexPropertyCommand(prereqCmd, complexConceptualProperty);
                    }

                    prereqCmd = cmd;
                    cp.EnqueueCommand(cmd);
                }
                else
                {
                    Debug.Assert(i == _properties.Count - 1, "This should be the last property");
                    CreateFragmentScalarPropertyCommand cmd = null;
                    if (prereqCmd == null)
                    {
                        if (_mode == Mode.EntityType)
                        {
                            cmd = new CreateFragmentScalarPropertyCommand(_conceptualEntityType, property, _tableColumn);
                        }
                        else
                        {
                            cmd = new CreateFragmentScalarPropertyCommand(_mappingFragment, property, _tableColumn);
                        }
                    }
                    else
                    {
                        cmd = new CreateFragmentScalarPropertyCommand(prereqCmd, property, _tableColumn);
                    }

                    cp.EnqueueCommand(cmd);
                    cp.Invoke();
                    _createdProperty = cmd.ScalarProperty;
                    return;
                }
            }
        }
        internal static bool UpdateEdmxAndEnvironment(ModelBuilderSettings settings)
        {
            var artifact = settings.Artifact as EntityDesignArtifact;
            if (artifact == null)
            {
                Debug.Fail("In trying to UpdateEdmxAndEnvironment(), No Artifact was found in the ModelBuilderSettings");
                return false;
            }

            // Update the app. or web.config, register build providers etc
            ConfigFileHelper.UpdateConfig(settings);

            if (settings.SsdlStringReader != null
                && settings.MslStringReader != null)
            {
                // Create the XmlReaders for the ssdl and msl text
                var ssdlXmlReader = XmlReader.Create(settings.SsdlStringReader);
                var mslXmlReader = XmlReader.Create(settings.MslStringReader);

                // Set up our post event to clear out the error list
                var cmd = new ReplaceSsdlAndMslCommand(ssdlXmlReader, mslXmlReader);
                cmd.PostInvokeEvent += (o, e) =>
                    {
                        var errorList = ErrorListHelper.GetSingleDocErrorList(e.CommandProcessorContext.Artifact.Uri);
                        if (errorList != null)
                        {
                            errorList.Clear();
                        }
                    };

                // Update the model (all inside 1 transaction so we don't get multiple undo's/redo's)
                var editingContext =
                    PackageManager.Package.DocumentFrameMgr.EditingContextManager.GetNewOrExistingContext(settings.Artifact.Uri);
                var cpc = new CommandProcessorContext(
                    editingContext,
                    EfiTransactionOriginator.GenerateDatabaseScriptFromModelId, Resources.Tx_GenerateDatabaseScriptFromModel);
                var cp = new CommandProcessor(cpc, cmd);
                var addUseLegacyProviderCommand = ModelHelper.CreateSetDesignerPropertyValueCommandFromArtifact(
                    cpc.Artifact,
                    OptionsDesignerInfo.ElementName,
                    OptionsDesignerInfo.AttributeUseLegacyProvider,
                    settings.UseLegacyProvider.ToString());
                if (addUseLegacyProviderCommand != null)
                {
                    cp.EnqueueCommand(addUseLegacyProviderCommand);
                }

                // When the user had a v2 edmx file (it can happen when creating a new empty model in a project targeting 
                // .NET Framework 4 and the project does not have refereces to any of EF dlls) and selected EF6 in 
                // the "create database from model" wizard we need to update the artifact to use v3 schemas otherwise
                // there will be a watermark saying that the edmx is not correct for the EF version and needs to be updated.
                // We only want to run this command if the version really changed to avoid the overhead.
                if (artifact.SchemaVersion != settings.TargetSchemaVersion)
                {
                    cp.EnqueueCommand(new RetargetXmlNamespaceCommand(artifact, settings.TargetSchemaVersion));
                }

                cp.Invoke();
            }

            // First let's get the canonical file path since DTE needs this
            if (!string.IsNullOrEmpty(settings.DdlFileName)
                && settings.DdlStringReader != null)
            {
                var canonicalFilePath = string.Empty;
                try
                {
                    var fi = new FileInfo(settings.DdlFileName);
                    canonicalFilePath = fi.FullName;
                }
                catch (Exception e)
                {
                    Debug.Fail(
                        "We should have caught this exception '" + e.Message + "' immediately after the user clicked the 'Finish' button");
                    VsUtils.ShowErrorDialog(
                        String.Format(
                            CultureInfo.CurrentCulture, ModelWizard.Properties.Resources.ErrorCouldNotParseDdlFileName, settings.DdlFileName,
                            e.Message));
                    return false;
                }

                // Output the DDL file, catch any Exceptions, display them, and revert
                // back to the last page of the wizard.
                try
                {
                    OutputDdl(canonicalFilePath, settings.DdlStringReader);
                }
                catch (Exception e)
                {
                    if (e.InnerException == null)
                    {
                        VsUtils.ShowErrorDialog(
                            String.Format(
                                CultureInfo.CurrentCulture, Resources.DatabaseCreation_ErrorWritingDdl, canonicalFilePath, e.Message));
                    }
                    else
                    {
                        VsUtils.ShowErrorDialog(
                            String.Format(
                                CultureInfo.CurrentCulture, Resources.DatabaseCreation_ErrorWritingDdlWithInner, canonicalFilePath,
                                e.Message, e.InnerException.Message));
                    }
                    return false;
                }

                // Add DDL file to the project if it is inside the project
                string relativePath;
                if (VsUtils.TryGetRelativePathInProject(settings.Project, canonicalFilePath, out relativePath))
                {
                    AddDDLFileToProject(settings.Project, canonicalFilePath);
                }

                // Open the DDL file if it is not already open
                IVsUIHierarchy hier;
                uint itemId;
                IVsWindowFrame frame;
                if (VsShellUtilities.IsDocumentOpen(
                    Services.ServiceProvider, canonicalFilePath, Guid.Empty, out hier, out itemId, out frame) == false)
                {
                    VsShellUtilities.OpenDocument(Services.ServiceProvider, canonicalFilePath);
                }
            }

            return true;
        }
        public void FunctionImportReturnComplexType()
        {
            UITestRunner.Execute(TestContext.TestName, 
                () =>
                    {
                        const string testName = "UndoRedo.FunctionImportReturnComplexType";

                        ExecuteUndoRedoTest(
                            testName, "NorthwindModel.edmx", (commandProcessorContext, artifact) =>
                                {
                                    var dte = VsIdeTestHostContext.Dte;

                                    var commandProcessor = new CommandProcessor(commandProcessorContext);
                                    var createComplexTypeCmd = new CreateComplexTypeCommand("Sales_by_year_result", true);
                                    commandProcessor.EnqueueCommand(createComplexTypeCmd);
                                    commandProcessor.EnqueueCommand(
                                        new CreateComplexTypePropertyCommand("Column1", createComplexTypeCmd, "Int32", false));
                                    commandProcessor.EnqueueCommand(
                                        new CreateFunctionImportCommand(
                                            artifact.GetFreshConceptualEntityContainer("NorthwindEntities"),
                                            artifact.GetFreshStorageFunction("Sales_by_Year"),
                                            "myfunctionimport",
                                            createComplexTypeCmd));

                                    commandProcessor.Invoke();

                                    Assert.IsNotNull(artifact.GetFreshComplexType("Sales_by_year_result"));
                                    Assert.IsNotNull(artifact.GetFreshComplexType("Sales_by_year_result"));
                                    Assert.IsNotNull(artifact.GetFreshFunctionImport("myfunctionimport"));
                                    Assert.AreEqual(
                                        "Collection(NorthwindModel.Sales_by_year_result)",
                                        ((SingleItemBinding<ComplexType>)artifact.GetFreshFunctionImport("myfunctionimport").ReturnType)
                                            .RefName);

                                    //Undo Redo Create FunctionImport
                                    dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), UndoCommand);
                                    Assert.IsNull(artifact.GetFreshComplexType("Sales_by_year_result"));
                                    Assert.IsNull(artifact.GetFreshFunctionImport("myfunctionimport"));
                                    dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), RedoCommand);
                                    Assert.IsNotNull(artifact.GetFreshComplexType("Sales_by_year_result"));
                                    Assert.IsNotNull(artifact.GetFreshFunctionImport("myfunctionimport"));
                                    Assert.AreEqual(
                                        "Collection(NorthwindModel.Sales_by_year_result)",
                                        ((SingleItemBinding<ComplexType>)artifact.GetFreshFunctionImport("myfunctionimport").ReturnType)
                                            .RefName);

                                    CommandProcessor.InvokeSingleCommand(
                                        commandProcessorContext,
                                        new CreateFunctionImportCommand(
                                            artifact.GetFreshConceptualEntityContainer("NorthwindEntities"),
                                            artifact.GetFreshStorageFunction("GetFreightCost"),
                                            "myfunctionimport2",
                                            "String"));

                                    Assert.IsNotNull(artifact.GetFreshFunctionImport("myfunctionimport2"));
                                    Assert.AreEqual(
                                        "Collection(String)",
                                        ((DefaultableValue<String>)artifact.GetFreshFunctionImport("myfunctionimport2").ReturnType).Value);

                                    createComplexTypeCmd = new CreateComplexTypeCommand("GetFreightCost_result", true);
                                    commandProcessor.EnqueueCommand(createComplexTypeCmd);
                                    commandProcessor.EnqueueCommand(
                                        new ChangeFunctionImportCommand(
                                            artifact.GetFreshConceptualEntityContainer("NorthwindEntities"),
                                            artifact.GetFreshFunctionImport("myfunctionimport2"),
                                            artifact.GetFreshStorageFunction("GetFreightCost"),
                                            "test123",
                                            /* isComposable */ BoolOrNone.FalseValue,
                                            createComplexTypeCmd));

                                    commandProcessor.Invoke();
                                    Assert.IsNull(artifact.GetFreshFunctionImport("myfunctionimport2"));
                                    Assert.IsNotNull(artifact.GetFreshFunctionImport("test123"));
                                    Assert.AreEqual(
                                        "Collection(NorthwindModel.GetFreightCost_result)",
                                        ((SingleItemBinding<ComplexType>)artifact.GetFreshFunctionImport("test123").ReturnType).RefName);
                                    Assert.IsNotNull(artifact.GetFreshComplexType("GetFreightCost_result"));

                                    // Undo redo "Change FunctionImport"
                                    dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), UndoCommand);
                                    Assert.IsNull(artifact.GetFreshFunctionImport("test123"));
                                    Assert.IsNotNull(artifact.GetFreshFunctionImport("myfunctionimport2"));
                                    Assert.AreEqual(
                                        "Collection(String)",
                                        ((DefaultableValue<String>)artifact.GetFreshFunctionImport("myfunctionimport2").ReturnType).Value);
                                    dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), RedoCommand);
                                    Assert.IsNull(artifact.GetFreshFunctionImport("myfunctionimport2"));
                                    Assert.IsNotNull(artifact.GetFreshFunctionImport("test123"));
                                    Assert.AreEqual(
                                        "Collection(NorthwindModel.GetFreightCost_result)",
                                        ((SingleItemBinding<ComplexType>)artifact.GetFreshFunctionImport("test123").ReturnType).RefName);
                                    Assert.IsNotNull(artifact.GetFreshComplexType("GetFreightCost_result"));
                                });
                    });
        }
        internal void watermarkLabel_LinkClickedDeleteAssociation(object sender, LinkLabelLinkClickedEventArgs e)
        {
            var association = _toolWindow.GetAssociationFromLastPrimarySelection();
            if (association == null)
            {
                Debug.Fail("association is null");
                return;
            }
            var associationSetMappings = association.AssociationSet.GetAntiDependenciesOfType<AssociationSetMapping>();
            Debug.Assert(_hostContext == _toolWindow.Context, "this.HostContext != to window.Context!");
            if (HostContext == null)
            {
                Debug.Fail("Host context is null");
            }
            else
            {
                var cpc = new CommandProcessorContext(
                    _hostContext,
                    EfiTransactionOriginator.MappingDetailsOriginatorId,
                    Resources.Tx_DeleteAssociationSetMapping);
                var cp = new CommandProcessor(cpc);
                foreach (var associationSetMapping in associationSetMappings)
                {
                    cp.EnqueueCommand(new DeleteEFElementCommand(associationSetMapping));
                }
                if (cp.CommandCount > 0)
                {
                    cp.Invoke();
                }
            }

            // reset watermark text to account for the deleted ASM.
            if (_toolWindow.CanEditMappingsForAssociation(association, false))
            {
                _toolWindow.SetUpAssociationDisplay();
            }
        }
        internal static void EditFunctionImport(
            EditingContext editingContext,
            FunctionImport functionImport,
            StorageEntityModel sModel,
            ConceptualEntityModel cModel,
            ConceptualEntityContainer cContainer,
            object selectedObject,
            string originatingId)
        {
            Debug.Assert(editingContext != null, "editingContext should not be null");
            Debug.Assert(!string.IsNullOrEmpty(originatingId), "originatingId should not be null or empty");

            // show dialog appropriate to framework version
            var result = ShowNewFunctionImportDialog(
                functionImport.Function,
                functionImport.LocalName.Value,
                sModel,
                cModel,
                cContainer,
                DialogsResource.NewFunctionImportDialog_EditFunctionImportTitle,
                selectedObject);

            // if user selected OK on the dialog then create the FunctionImport
            if (DialogResult.OK == result.DialogResult)
            {
                var commands = new List<Command>();
                var cp = new CommandProcessor(editingContext, originatingId, Resources.Tx_UpdateFunctionImport);
                CreateComplexTypeCommand createComplexTypeCommand = null;

                // Make the decision based on what is returned by the dialog.
                // If return type is a string and result schema is not null, that means the user would like to create a new complex type for the function import return.
                if (result.ReturnType is string
                    && result.Schema != null)
                {
                    createComplexTypeCommand = CreateMatchingFunctionImportCommand.AddCreateComplexTypeCommands(
                        sModel, result.ReturnType as string, result.Schema.RawColumns, commands);
                }
                    // If ReturnType is a complex type and result schema is not null, the complex type needs to be updated to be in sync with schema columns.
                else if (result.ReturnType is ComplexType
                         && result.Schema != null)
                {
                    var complexType = result.ReturnType as ComplexType;
                    // Create Column properties dictionary. The keys will be either property's type-mapping column name if availabe or property's name.
                    var propertiesDictionary =
                        complexType.Properties().ToDictionary(p => EdmUtils.GetFunctionImportResultColumnName(functionImport, p));
                    CreateMatchingFunctionImportCommand.AddChangeComplexTypePropertiesCommands(
                        complexType, propertiesDictionary, result.Schema.RawColumns, commands);
                }

                // construct Dictionary mapping property name to column name for FunctionImportMapping
                IDictionary<string, string> mapPropertyNameToColumnName = null;
                if (result.Schema != null)
                {
                    mapPropertyNameToColumnName =
                        ModelHelper.ConstructComplexTypePropertyNameToColumnNameMapping(result.Schema.Columns.Select(c => c.Name).ToList());
                }

                // change the FunctionImport and FunctionImportMapping to match
                ChangeFunctionImportCommand cmdFuncImpSproc = null;
                // if result.IsComposable is true then set to True, but if false then use None if existing value is None, otherwise False
                var resultIsComposable = (result.IsComposable
                                              ? BoolOrNone.TrueValue
                                              : (BoolOrNone.NoneValue == functionImport.IsComposable.Value
                                                     ? BoolOrNone.NoneValue
                                                     : BoolOrNone.FalseValue));
                if (createComplexTypeCommand == null)
                {
                    cmdFuncImpSproc = new ChangeFunctionImportCommand(
                        cContainer, functionImport, result.Function, result.FunctionName, resultIsComposable, true, result.ReturnType);
                    // Create explicit function-import result type mapping if the return type is a complex type.
                    if (result.ReturnType is ComplexType)
                    {
                        cmdFuncImpSproc.PostInvokeEvent += (o, eventArgs) =>
                            {
                                if (functionImport != null
                                    && functionImport.FunctionImportMapping != null)
                                {
                                    // CreateFunctionImportTypeMappingCommand will be no op function-import's return is unchanged.
                                    CommandProcessor.InvokeSingleCommand(
                                        cp.CommandProcessorContext
                                        ,
                                        new CreateFunctionImportTypeMappingCommand(
                                            functionImport.FunctionImportMapping, result.ReturnType as ComplexType)
                                            {
                                                CreateDefaultScalarProperties = true,
                                                PropertyNameToColumnNameMap = mapPropertyNameToColumnName
                                            });
                                }
                            };
                    }
                }
                else
                {
                    // Pass in the pre-req command to create complex type to the command.
                    cmdFuncImpSproc = new ChangeFunctionImportCommand(
                        cContainer, functionImport, result.Function, result.FunctionName,
                        resultIsComposable, createComplexTypeCommand);
                    // Create explicit function-import result type mapping if the return type is a complex type.
                    cmdFuncImpSproc.PostInvokeEvent += (o, eventArgs) =>
                        {
                            if (functionImport != null
                                && functionImport.FunctionImportMapping != null)
                            {
                                CommandProcessor.InvokeSingleCommand(
                                    cp.CommandProcessorContext,
                                    new CreateFunctionImportTypeMappingCommand(
                                        functionImport.FunctionImportMapping, createComplexTypeCommand)
                                        {
                                            CreateDefaultScalarProperties = true,
                                            PropertyNameToColumnNameMap = mapPropertyNameToColumnName
                                        });
                            }
                        };
                }
                commands.Add(cmdFuncImpSproc);
                commands.ForEach(x => cp.EnqueueCommand(x));
                cp.Invoke();
            }
        }
        internal override void CreateModelItem(CommandProcessorContext cpc, EditingContext context, EFElement underlyingModelItem)
        {
            Debug.Assert(context != null, "null context");

            Debug.Assert(Function == null, "Don't call this method if we already have a ModelItem");
            Debug.Assert(MappingFunctionEntityType.EntityType != null, "The parent item isn't set up correctly");

            Debug.Assert(underlyingModelItem != null, "null underlyingModelItem");

            var function = underlyingModelItem as Function;
            Debug.Assert(
                function != null, "underlyingModelItem must be of type Function, actual type = " + underlyingModelItem.GetType().FullName);
            Debug.Assert(!function.EntityModel.IsCSDL, "The function must be in the SSDL");

            Context = context;

            // create a context if we weren't passed one
            if (cpc == null)
            {
                cpc = new CommandProcessorContext(
                    Context, EfiTransactionOriginator.MappingDetailsOriginatorId, Resources.Tx_CreateFunctionMapping);
            }

            // create the commands
            var cmd = new CreateFunctionMappingCommand(MappingFunctionEntityType.EntityType, function, null, _functionType);
            // set up our post event to fix up the view model
            cmd.PostInvokeEvent += (o, eventsArgs) =>
                {
                    var mf = cmd.ModificationFunction;
                    Debug.Assert(mf != null, "null ModificationFunction");

                    // fix up our view model
                    ModelItem = mf;
                    // The parent item for the function mapping view model always has 3 children; insert, update and delete items.  If there isn’t 
                    // a function mapped for any of these, then there is still a view model item since we want to display the ‘creator node’ text.
                    // Calling this.Parent.AddChild(this) here would make the parent think it had a new child instead of updating the existing one - 
                    // so it is correct to _not_ call it here.
                };

            var cmd2 = new DelegateCommand(
                () =>
                    {
                        var mf = ModificationFunction;
                        Debug.Assert(
                            mf != null,
                            "Null ModificationFunction when trying to create view-model dummy nodes in MappingModificationFunctionMapping.CreateModelItem()");

                        if (mf != null)
                        {
                            //set up _properties and _resultBindings here as they are dummy ViewModel nodes
                            // (i.e. don't correspond to any underlying ModelItem)
                            _properties = new MappingFunctionScalarProperties(context, mf, this);
                            _resultBindings = new MappingResultBindings(context, mf, this);
                            _properties.Parent.AddChild(_properties);
                            _resultBindings.Parent.AddChild(_resultBindings);

                            // now ensure _properties scalar properties children have been calculated
                            // (this creates scalar properties with just the column info 
                            // since this ModificationFunction has not yet been mapped)
                            _properties.LoadScalarProperties();

                            // now try and do some match ups between the function and the entity
                            var mappedEntityType = MappingFunctionEntityType.EntityType as ConceptualEntityType;

                            Debug.Assert(
                                MappingFunctionEntityType.EntityType == null || mappedEntityType != null,
                                "EntityType is not ConceptualEntityType");

                            if (mappedEntityType != null)
                            {
                                foreach (var mfsp in _properties.ScalarProperties)
                                {
                                    // Try to do some auto-matching of the sproc's parameters to the EntityType's properties.
                                    // Search for a property in the mapped EntityType's inheritance hierarchy that matches the
                                    // parameter's name. First search this EntityType (both its scalar and complex properties),
                                    // then search its parents scalar and complex properties and so on up the hierarchy
                                    var propNameToSearchFor = mfsp.StoreParameter.LocalName.Value;
                                    var propList = new List<Property>();
                                    var entityTypeToSearch = mappedEntityType;
                                    // reset this back to the mapped EntityType each time through the loop
                                    while (entityTypeToSearch != null
                                           && false
                                           == ModelHelper.FindScalarPropertyPathByLocalName(
                                               entityTypeToSearch, propNameToSearchFor, out propList))
                                    {
                                        if (entityTypeToSearch.BaseType == null)
                                        {
                                            // safety code - this should not happen but will prevent an infinite loop if it does
                                            entityTypeToSearch = null;
                                        }
                                        else
                                        {
                                            entityTypeToSearch = entityTypeToSearch.BaseType.Target;
                                        }
                                    }

                                    // if propList is still empty that means we did not find a match - so leave the parameter unmapped
                                    if (propList.Count > 0)
                                    {
                                        mfsp.CreateModelItem(cpc, _context, propList);
                                    }
                                }
                            }
                        }
                    });

            try
            {
                // now make the change
                var cp = new CommandProcessor(cpc);
                cp.EnqueueCommand(cmd);
                cp.EnqueueCommand(cmd2);
                cp.Invoke();
            }
            catch
            {
                ModelItem = null;
                ClearChildren();

                throw;
            }
        }
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            Debug.Assert(
                _mode == Mode.EntityType || _mode == Mode.MappingFragment, "Unknown mode set in CreateFragmentScalarPropertyTreeCommand");

            var cp = new CommandProcessor(cpc);
            CreateFragmentComplexPropertyCommand prereqCmd = null;
            for (var i = 0; i < _properties.Count; i++)
            {
                var property = _properties[i];
                var complexConceptualProperty = property as ComplexConceptualProperty;
                if (complexConceptualProperty != null)
                {
                    Debug.Assert(i < _properties.Count - 1, "Last property shouldn't be ComplexConceptualProperty");
                    CreateFragmentComplexPropertyCommand cmd = null;
                    if (prereqCmd == null)
                    {
                        if (_mode == Mode.EntityType)
                        {
                            cmd = new CreateFragmentComplexPropertyCommand(_conceptualEntityType, complexConceptualProperty, _tableColumn);
                        }
                        else
                        {
                            cmd = new CreateFragmentComplexPropertyCommand(_mappingFragment, complexConceptualProperty);
                        }
                    }
                    else
                    {
                        cmd = new CreateFragmentComplexPropertyCommand(prereqCmd, complexConceptualProperty);
                    }

                    prereqCmd = cmd;
                    cp.EnqueueCommand(cmd);
                }
                else
                {
                    Debug.Assert(i == _properties.Count - 1, "This should be the last property");
                    CreateFragmentScalarPropertyCommand cmd = null;
                    if (prereqCmd == null)
                    {
                        if (_mode == Mode.EntityType)
                        {
                            cmd = new CreateFragmentScalarPropertyCommand(_conceptualEntityType, property, _tableColumn);
                        }
                        else
                        {
                            cmd = new CreateFragmentScalarPropertyCommand(_mappingFragment, property, _tableColumn);
                        }
                    }
                    else
                    {
                        cmd = new CreateFragmentScalarPropertyCommand(prereqCmd, property, _tableColumn);
                    }

                    cp.EnqueueCommand(cmd);
                    cp.Invoke();
                    _createdProperty = cmd.ScalarProperty;
                    return;
                }
            }
        }
        internal static void DoMigrate(CommandProcessorContext cpc, EntityDesignArtifact artifact)
        {
            var xmlModelProvider = artifact.XmlModelProvider as VSXmlModelProvider;
            Debug.Assert(xmlModelProvider != null, "Artifact's model provider is not type of VSXmlModelProvider.");
            if ((xmlModelProvider != null)
                && (xmlModelProvider.UndoManager != null))
            {
                var undoManager = xmlModelProvider.UndoManager;
                try
                {
                    // We need to temporarily disable the Undo Manager because this operation is not undoable.
                    if (undoManager != null)
                    {
                        undoManager.Enable(0);
                    }

                    var command = new MigrateDiagramInformationCommand(artifact);
                    var processor = new CommandProcessor(cpc, shouldNotifyObservers: false);
                    processor.EnqueueCommand(command);
                    processor.Invoke();

                    Debug.Assert(artifact.DiagramArtifact != null, "Diagram artifact should have been created by now.");
                    if (artifact.DiagramArtifact != null)
                    {
                        // Ensure that diagram file is added to the project.
                        var service = PackageManager.Package.GetService(typeof(DTE)) as DTE;
                        service.ItemOperations.AddExistingItem(artifact.DiagramArtifact.Uri.LocalPath);

                        // Reload the artifacts.
                        artifact.ReloadArtifact();
                        artifact.IsDirty = true;

                        // The code below ensures mapping window and model-browser window are refreshed.
                        Debug.Assert(
                            PackageManager.Package.DocumentFrameMgr != null, "Could not find the DocumentFrameMgr for this package");
                        if (PackageManager.Package.DocumentFrameMgr != null)
                        {
                            PackageManager.Package.DocumentFrameMgr.SetCurrentContext(cpc.EditingContext);
                        }
                    }
                }
                finally
                {
                    if (undoManager != null)
                    {
                        undoManager.Enable(1);
                    }
                }
            }
        }
        public override void OnDoubleClick(DiagramPointEventArgs e)
        {
            var association = ModelElement;
            if (association != null)
            {
                var diagram = Diagram as EntityDesignerDiagram;
                if (diagram != null)
                {
                    var ec = diagram.GetModel().EditingContext;
                    var xref = ModelToDesignerModelXRef.GetModelToDesignerModelXRef(ec);

                    var modelAssociation = xref.GetExisting(association) as Model.Entity.Association;
                    Debug.Assert(modelAssociation != null, "couldn't find model association for connector");
                    if (modelAssociation != null)
                    {
                        var commands = ReferentialConstraintDialog.LaunchReferentialConstraintDialog(modelAssociation);

                        var cpc = new CommandProcessorContext(
                            ec, EfiTransactionOriginator.EntityDesignerOriginatorId, Resources.Tx_ReferentialContraint);
                        var cp = new CommandProcessor(cpc);
                        foreach (var c in commands)
                        {
                            cp.EnqueueCommand(c);
                        }
                        cp.Invoke();
                    }
                }
            }
        }
        internal override void CreateModelItem(CommandProcessorContext cpc, EditingContext context, EFElement underlyingModelItem)
        {
            Debug.Assert(context != null, "The context argument cannot be null");
            Debug.Assert(StorageEntityType == null, "Don't call this method if we already have a ModelItem");
            Debug.Assert(MappingConceptualEntityType.ConceptualEntityType != null, "The parent item isn't set up correctly");
            Debug.Assert(underlyingModelItem != null, "The underlyingModelItem cannot be null");
            var storeEntityType = underlyingModelItem as EntityType;
            Debug.Assert(
                storeEntityType != null,
                "underlyingModelItem must be of type EntityType, actual type = " + underlyingModelItem.GetType().FullName);
            Debug.Assert(storeEntityType.EntityModel.IsCSDL == false, "The storageEntityType must not be a CSDL EntityType");

            Context = context;
            ColumnMappings.Context = context;

            // create a context if we weren't passed one
            if (cpc == null)
            {
                cpc = new CommandProcessorContext(
                    Context, EfiTransactionOriginator.MappingDetailsOriginatorId, Resources.Tx_CreateMappingFragment);
            }

            // create the MappingFragment - if we already have a default EntityTypeMapping then just add
            // the MappingFragment to that mapping, otherwise if we already have an IsTypeOf
            // EntityTypeMapping then add the MappingFragment to that, otherwise create an IsTypeOf
            // EntityTypeMapping and add the MappingFragment to that
            var cet = MappingConceptualEntityType.ConceptualEntityType;
            var defaultEtm = ModelHelper.FindEntityTypeMapping(cpc, cet, EntityTypeMappingKind.Default, false);
            var etmKind = (defaultEtm == null ? EntityTypeMappingKind.IsTypeOf : EntityTypeMappingKind.Default);
            var cmd = new CreateMappingFragmentCommand(cet, storeEntityType, etmKind);

            // add post-invoke event to fix up our view model
            cmd.PostInvokeEvent += (o, eventsArgs) =>
                {
                    // fix up our view model
                    ModelItem = storeEntityType;
                    Parent.AddChild(this);

                    // assign the table to our container node as well
                    ColumnMappings.ModelItem = storeEntityType;

                    // now try and do some match ups between the entity and the table
                    var mappingStrategy = ModelHelper.DetermineCurrentInheritanceStrategy(cet);
                    var topMostBaseType = cet.ResolvableTopMostBaseType;
                    foreach (var child in ColumnMappings.Children)
                    {
                        var msp = child as MappingScalarProperty;
                        if (msp != null)
                        {
                            List<Property> properties;
                            if (ModelHelper.FindScalarPropertyPathByLocalName(cet, msp.ColumnName, out properties))
                            {
                                msp.CreateModelItem(cpc, _context, properties);
                            }
                            else if (InheritanceMappingStrategy.TablePerType == mappingStrategy
                                     &&
                                     ModelHelper.FindScalarPropertyPathByLocalName(topMostBaseType, msp.ColumnName, out properties))
                            {
                                msp.CreateModelItem(cpc, _context, properties);
                            }
                        }
                    }
                };

            try
            {
                // now update the model
                var cp = new CommandProcessor(cpc);
                cp.EnqueueCommand(cmd);
                cp.Invoke();
            }
            catch
            {
                ModelItem = null;
                ColumnMappings.ModelItem = null;
                Parent.RemoveChild(this);
                throw;
            }
        }
        /// <summary>
        ///     This helper function will create a complex type using default name.
        ///     NOTE: If the cpc already has an active transaction, these changes will be in that transaction
        ///     and the caller of this helper method must commit it to see these changes commited.
        /// </summary>
        /// <param name="cpc"></param>
        /// <returns>The new ComplexType</returns>
        internal static ComplexType CreateComplexTypeWithDefaultName(CommandProcessorContext cpc)
        {
            var service = cpc.EditingContext.GetEFArtifactService();
            var artifact = service.Artifact;

            // the model that we want to add the complex type to
            var model = artifact.ConceptualModel();
            if (model == null)
            {
                throw new CannotLocateParentItemException();
            }

            var complexTypeName = ModelHelper.GetUniqueNameWithNumber(typeof(ComplexType), model, Resources.Model_DefaultComplexTypeName);

            // go create it
            var cp = new CommandProcessor(cpc);
            var cmd = new CreateComplexTypeCommand(complexTypeName, false);
            cp.EnqueueCommand(cmd);
            cp.Invoke();
            return cmd.ComplexType;
        }
        // <summary>
        //     NOTE: The association set mapping view model doesn't keep a reference to the mapping model item. Instead, it
        //     keeps it to the AssociationSet and then it can find the AssociationSetMapping as an anti-dep.  We don't need to clear
        //     or set the ModelItem property.
        // </summary>
        internal override void CreateModelItem(CommandProcessorContext cpc, EditingContext context, EFElement underlyingModelItem)
        {
            Debug.Assert(context != null, "The context argument cannot be null");
            Debug.Assert(AssociationSet.AssociationSetMapping == null, "Don't call this method if we already have a mapping");
            Debug.Assert(underlyingModelItem != null, "The underlyingModelItem cannot be null");
            var storeEntityType = underlyingModelItem as EntityType;
            Debug.Assert(
                storeEntityType != null,
                "underlyingModelItem must be of type EntityType, actual type = " + underlyingModelItem.GetType().FullName);
            Debug.Assert(!storeEntityType.EntityModel.IsCSDL, "The storageEntityType must not be a CSDL EntityType");

            Context = context;

            // create a context if we weren't passed one
            if (cpc == null)
            {
                cpc = new CommandProcessorContext(
                    Context, EfiTransactionOriginator.MappingDetailsOriginatorId, Resources.Tx_CreateAssociationSetMapping);
            }

            // create the item
            var cmd1 = new CreateAssociationSetMappingCommand(MappingAssociation.Association, storeEntityType);

            // now try and do some match ups by name
            var cmd2 = new DelegateCommand(
                () =>
                    {
                        Parent.AddChild(this);

                        foreach (var child in Children)
                        {
                            var end = child as MappingAssociationSetEnd;
                            if (end != null)
                            {
                                foreach (var child2 in end.Children)
                                {
                                    var mesp = child2 as MappingEndScalarProperty;
                                    if (mesp != null)
                                    {
                                        var tableColumn =
                                            MappingAssociationSet.StorageEntityType.GetFirstNamedChildByLocalName(mesp.Property, true) as
                                            Property;
                                        if (tableColumn != null)
                                        {
                                            mesp.CreateModelItem(cpc, _context, tableColumn);
                                        }
                                    }
                                }
                            }
                        }
                    });

            // now make the change
            var cp = new CommandProcessor(cpc);
            cp.EnqueueCommand(cmd1);
            cp.EnqueueCommand(cmd2);
            cp.Invoke();
        }
        public void Mapping_General_Blank()
        {
            UITestRunner.Execute(TestContext.TestName, 
                () =>
                    {
                        const string typePrefix = "Mapping_General_Blank";
                        const string testName = "UndoRedo." + typePrefix;

                        ExecuteUndoRedoTest(
                            testName, "BlankModel.edmx", (commandProcessorContext, artifact) =>
                                {
                                    const string entityType1Name = typePrefix + "_EntityType1";
                                    const string entityType2Name = typePrefix + "_EntityType2";
                                    const string entitySetName = typePrefix + "_EntitySet";

                                    var dte = VsIdeTestHostContext.Dte;

                                    CreateDefaultEntityType(commandProcessorContext, entityType1Name, entitySetName);
                                    CreateEntityTypeCommand.CreateConceptualEntityTypeAndEntitySetAndProperty(
                                        commandProcessorContext,
                                        entityType2Name,
                                        entitySetName,
                                        /*createKeyProperty*/ false,
                                        null,
                                        null,
                                        null,
                                        /*uniquifyNames*/ true);

                                    new CommandProcessor(
                                        commandProcessorContext,
                                        new CreateInheritanceCommand(
                                            artifact.GetFreshConceptualEntity(entityType2Name),
                                            artifact.GetFreshConceptualEntity(entityType1Name))).Invoke();

                                    // CREATE TWO ENTITY TYPE MAPPINGS WITHIN THE SAME ENTITY SET MAPPING
                                    var commandProcessor = new CommandProcessor(commandProcessorContext);
                                    commandProcessor.EnqueueCommand(
                                        new CreateEntityTypeMappingCommand(artifact.GetFreshConceptualEntity(entityType1Name)));
                                    commandProcessor.EnqueueCommand(
                                        new CreateEntityTypeMappingCommand(artifact.GetFreshConceptualEntity(entityType2Name)));
                                    commandProcessor.Invoke();

                                    Assert.AreEqual(2, artifact.GetFreshEntitySetMapping(entitySetName).EntityTypeMappings().Count);

                                    // Undo redo "Create two EntityTypeMappings within same EntitySetMapping"
                                    dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), UndoCommand);
                                    Assert.IsNull(artifact.GetFreshEntitySetMapping(entitySetName));
                                    Assert.IsNotNull(artifact.GetFreshConceptualEntity(entityType1Name));
                                    Assert.IsNotNull(artifact.GetFreshConceptualEntity(entityType2Name));
                                    dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), RedoCommand);
                                    Assert.AreEqual(2, artifact.GetFreshEntitySetMapping(entitySetName).EntityTypeMappings().Count);
                                });
                    });
        }
        // <summary>
        //     Show the dialog to edit an existing enum type.
        // </summary>
        public static void EditEnumType(
            EditingContext editingContext, string originatingId, EnumTypeViewModel enumTypeViewModel, EventHandler onDialogActivated = null)
        {
            if (editingContext == null)
            {
                throw new ArgumentNullException("editingContext");
            }
            if (enumTypeViewModel == null)
            {
                throw new ArgumentNullException("enumTypeViewModel");
            }

            Debug.Assert(
                !enumTypeViewModel.IsNew,
                typeof(EntityDesignViewModelHelper).Name + ".EditEnumType: Expected existing enum type is passed in");

            if (enumTypeViewModel.IsNew == false)
            {
                var result = ShowEnumTypeDialog(enumTypeViewModel, onDialogActivated);

                var enumType = enumTypeViewModel.EnumType;
                if (result == true)
                {
                    var cp = new CommandProcessor(editingContext, originatingId, Resources.Tx_UpdateEnumType);

                    cp.EnqueueCommand(
                        new SetEnumTypeFacetCommand(
                            enumType
                            , enumTypeViewModel.Name, enumTypeViewModel.SelectedUnderlyingType
                            , enumTypeViewModel.IsReferenceExternalType ? enumTypeViewModel.ExternalTypeName : String.Empty
                            , enumTypeViewModel.IsFlag));

                    // We delete and create enum type members.
                    // TODO: we might want to do intelligent edit for large number of enum type member.
                    foreach (var enumTypeMember in enumType.Members())
                    {
                        cp.EnqueueCommand(enumTypeMember.GetDeleteCommand());
                    }

                    foreach (var enumTypeMemberViewModel in enumTypeViewModel.Members)
                    {
                        if (String.IsNullOrWhiteSpace(enumTypeMemberViewModel.Name) == false)
                        {
                            cp.EnqueueCommand(
                                new CreateEnumTypeMemberCommand(enumType, enumTypeMemberViewModel.Name, enumTypeMemberViewModel.Value));
                        }
                    }

                    cp.Invoke();
                }
            }
        }
        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());
        }
        private void ProcessViewModelChanges(string name, IList<ViewModelChange> viewModelChanges)
        {
            if (viewModelChanges != null
                && viewModelChanges.Count > 0)
            {
                var context = new EfiTransactionContext();
                var containsDiagramChanges = viewModelChanges.Any(vmc => vmc.IsDiagramChange);
                context.Add(
                    EfiTransactionOriginator.TransactionOriginatorDiagramId,
                    new ModelDesigner.DiagramContextItem(DiagramId, containsDiagramChanges));

                var cpc = new CommandProcessorContext(
                    EditingContext, EfiTransactionOriginator.EntityDesignerOriginatorId, name, null, context);
                var cp = new CommandProcessor(cpc);

                // check if the DeleteUnmappedStorageEntitySetsProperty property is set
                if (Store.PropertyBag.ContainsKey(DeleteUnmappedStorageEntitySetsProperty))
                {
                    // if the property is set then unset it and add a
                    // command to remove these for each item in the master list
                    var unmappedMasterList =
                        Store.PropertyBag[DeleteUnmappedStorageEntitySetsProperty] as List<ICollection<StorageEntitySet>>;
                    Store.PropertyBag.Remove(DeleteUnmappedStorageEntitySetsProperty);

                    if (unmappedMasterList != null)
                    {
                        foreach (var unmappedEntitySets in unmappedMasterList)
                        {
                            var duse = new DeleteUnmappedStorageEntitySetsCommand(unmappedEntitySets);
                            cp.EnqueueCommand(duse);
                        }
                    }
                }

                var setParentUndoUnit = false;
                try
                {
                    if (cpc.EditingContext.ParentUndoUnitStarted == false)
                    {
                        cpc.EditingContext.ParentUndoUnitStarted = true;
                        cpc.Artifact.XmlModelProvider.BeginUndoScope(name);
                        setParentUndoUnit = true;
                    }

                    var cmd = new DelegateCommand(
                        () =>
                            {
                                foreach (var change in viewModelChanges)
                                {
                                    change.Invoke(cpc);
                                }
                            });

                    cp.EnqueueCommand(cmd);
                    cp.Invoke();
                }
                catch (Exception e)
                {
                    if (!(e is CommandValidationFailedException || e is FileNotEditableException))
                    {
                        Debug.Fail("Exception thrown while committing change to Model. " + e.Message);
                    }
                    throw;
                }
                finally
                {
                    if (setParentUndoUnit)
                    {
                        cpc.EditingContext.ParentUndoUnitStarted = false;
                        cpc.Artifact.XmlModelProvider.EndUndoScope();
                    }
                }
            }
        }