Exemple #1
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);
        }
        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;
        }
        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 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 #5
0
        /// <summary>
        ///     The method will do the following:
        ///     - Creates a complex property with specified typeName in the entity-type.
        ///     - The complex property will be inserted in the specified position.
        ///     - Set the property's facet values.
        /// </summary>
        /// <param name="cpc"></param>
        /// <param name="name">The name of the new property</param>
        /// <param name="entityType">The entity to create this property in</param>
        /// <param name="typeName">The complex property name.</param>
        /// <param name="concurrencyMode">The property concurrencyMode facet value.</param>
        /// <param name="getterAccessModifier">The property getterAccessModifier facet value.</param>
        /// <param name="setterAccessModifier">The property setterAccessModifier facet value.</param>
        /// <param name="insertPosition">Information where the property should be inserted to. If the parameter is null, the property will be placed as the last property of the entity.</param>
        /// <returns></returns>
        internal static ComplexConceptualProperty CreateComplexProperty(
            CommandProcessorContext cpc, string name, EntityType entityType, string typeName,
            string concurrencyMode, string getterAccessModifier, string setterAccessModifier, InsertPropertyPosition insertPosition)
        {
            var cmd = new CreateComplexPropertyCommand(name, entityType, typeName, insertPosition);

            cmd.PostInvokeEvent += (o, eventsArgs) =>
            {
                var complexProperty = cmd.Property;
                Debug.Assert(complexProperty != null, "We didn't get good property out of the command");
                if (complexProperty != null)
                {
                    // set ComplexProperty attributes
                    if (!String.IsNullOrEmpty(concurrencyMode))
                    {
                        complexProperty.ConcurrencyMode.Value = concurrencyMode;
                    }
                    if (!String.IsNullOrEmpty(getterAccessModifier))
                    {
                        complexProperty.Getter.Value = getterAccessModifier;
                    }
                    if (!String.IsNullOrEmpty(setterAccessModifier))
                    {
                        complexProperty.Setter.Value = setterAccessModifier;
                    }
                }
            };
            var cp = new CommandProcessor(cpc, cmd);

            cp.Invoke();
            return(cmd.Property);
        }
        /// <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);
                    }
                }
            }
        }
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            // first create new ComplexType
            _createdComplexType = CreateComplexTypeCommand.CreateComplexTypeWithDefaultName(cpc);
            // add a copy of Entity properties to the ComplexType
            var copyCmd      = new CopyPropertiesCommand(new PropertiesClipboardFormat(_properties), _createdComplexType);
            var propertyName = ModelHelper.GetUniqueConceptualPropertyName(
                ComplexConceptualProperty.DefaultComplexPropertyName, _entityType);
            // add a new Property of created ComplexType to the Entity
            var createCPCmd = new CreateComplexPropertyCommand(propertyName, _entityType, _createdComplexType);
            var cp          = new CommandProcessor(cpc, copyCmd, createCPCmd);

            cp.Invoke();
            _createdComplexProperty = createCPCmd.Property;

            // preserve mappings
            foreach (var property in _properties)
            {
                if (property is ComplexConceptualProperty)
                {
                    var createdComplexTypeProperty =
                        _createdComplexType.FindPropertyByLocalName(property.LocalName.Value) as ComplexConceptualProperty;
                    Debug.Assert(createdComplexTypeProperty != null, "Copied complex property not found");
                    if (createdComplexTypeProperty != null)
                    {
                        foreach (var complexPropertyMapping in property.GetAntiDependenciesOfType <ComplexProperty>())
                        {
                            PreserveComplexPropertyMapping(cpc, complexPropertyMapping, createdComplexTypeProperty);
                        }

                        foreach (var fcp in property.GetAntiDependenciesOfType <FunctionComplexProperty>())
                        {
                            PreserveFunctionComplexPropertyMapping(cpc, fcp, createdComplexTypeProperty);
                        }
                    }
                }
                else
                {
                    var createdComplexTypeProperty = _createdComplexType.FindPropertyByLocalName(property.LocalName.Value);
                    Debug.Assert(createdComplexTypeProperty != null, "Copied property not found");
                    if (createdComplexTypeProperty != null)
                    {
                        // update EntityTypeMappings
                        foreach (var scalarPropertyMapping in property.GetAntiDependenciesOfType <ScalarProperty>())
                        {
                            PreserveScalarPropertyMapping(cpc, scalarPropertyMapping, createdComplexTypeProperty);
                        }

                        // update ModificationFunctionMappings
                        foreach (var fsp in property.GetAntiDependenciesOfType <FunctionScalarProperty>())
                        {
                            PreserveFunctionScalarPropertyMapping(cpc, fsp, createdComplexTypeProperty);
                        }
                    }
                }
            }
        }
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            // first create new ComplexType
            _createdComplexType = CreateComplexTypeCommand.CreateComplexTypeWithDefaultName(cpc);
            // add a copy of Entity properties to the ComplexType
            var copyCmd = new CopyPropertiesCommand(new PropertiesClipboardFormat(_properties), _createdComplexType);
            var propertyName = ModelHelper.GetUniqueConceptualPropertyName(
                ComplexConceptualProperty.DefaultComplexPropertyName, _entityType);
            // add a new Property of created ComplexType to the Entity
            var createCPCmd = new CreateComplexPropertyCommand(propertyName, _entityType, _createdComplexType);
            var cp = new CommandProcessor(cpc, copyCmd, createCPCmd);
            cp.Invoke();
            _createdComplexProperty = createCPCmd.Property;

            // preserve mappings
            foreach (var property in _properties)
            {
                if (property is ComplexConceptualProperty)
                {
                    var createdComplexTypeProperty =
                        _createdComplexType.FindPropertyByLocalName(property.LocalName.Value) as ComplexConceptualProperty;
                    Debug.Assert(createdComplexTypeProperty != null, "Copied complex property not found");
                    if (createdComplexTypeProperty != null)
                    {
                        foreach (var complexPropertyMapping in property.GetAntiDependenciesOfType<ComplexProperty>())
                        {
                            PreserveComplexPropertyMapping(cpc, complexPropertyMapping, createdComplexTypeProperty);
                        }

                        foreach (var fcp in property.GetAntiDependenciesOfType<FunctionComplexProperty>())
                        {
                            PreserveFunctionComplexPropertyMapping(cpc, fcp, createdComplexTypeProperty);
                        }
                    }
                }
                else
                {
                    var createdComplexTypeProperty = _createdComplexType.FindPropertyByLocalName(property.LocalName.Value);
                    Debug.Assert(createdComplexTypeProperty != null, "Copied property not found");
                    if (createdComplexTypeProperty != null)
                    {
                        // update EntityTypeMappings
                        foreach (var scalarPropertyMapping in property.GetAntiDependenciesOfType<ScalarProperty>())
                        {
                            PreserveScalarPropertyMapping(cpc, scalarPropertyMapping, createdComplexTypeProperty);
                        }

                        // update ModificationFunctionMappings
                        foreach (var fsp in property.GetAntiDependenciesOfType<FunctionScalarProperty>())
                        {
                            PreserveFunctionScalarPropertyMapping(cpc, fsp, createdComplexTypeProperty);
                        }
                    }
                }
            }
        }
        /// <summary>
        ///     Creates scalar property with a default, unique name and passed type
        /// </summary>
        /// <param name="cpc"></param>
        /// <param name="parentComplexType">parent for new property</param>
        /// <param name="type">type for new property</param>
        /// <returns></returns>
        internal static Property CreateDefaultProperty(CommandProcessorContext cpc, ComplexType parentComplexType, string type)
        {
            var name = ModelHelper.GetUniqueName(typeof(ConceptualProperty), parentComplexType, Property.DefaultPropertyName);
            var cmd  = new CreateComplexTypePropertyCommand(name, parentComplexType, type, false);

            var cp = new CommandProcessor(cpc, cmd);

            cp.Invoke();

            return(cmd.Property);
        }
Exemple #11
0
        internal static Association CreateAssociationAndAssociationSetWithDefaultNames(
            CommandProcessorContext cpc, ConceptualEntityType end1Entity, ConceptualEntityType end2Entity)
        {
            var service  = cpc.EditingContext.GetEFArtifactService();
            var artifact = service.Artifact;

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

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

            // Should have discovered the association name through the behavior service. Going back to default
            var associationName = ModelHelper.GetUniqueName(
                typeof(Association), model, end1Entity.LocalName.Value + end2Entity.LocalName.Value);

            // pluralization service is based on English only for Dev10
            IPluralizationService pluralizationService = null;
            var pluralize = ModelHelper.GetDesignerPropertyValueFromArtifactAsBool(
                OptionsDesignerInfo.ElementName,
                OptionsDesignerInfo.AttributeEnablePluralization, OptionsDesignerInfo.EnablePluralizationDefault, artifact);

            if (pluralize)
            {
                pluralizationService = DependencyResolver.GetService <IPluralizationService>();
            }

            var end1Multiplicity = ModelConstants.Multiplicity_One;
            var end2Multiplicity = ModelConstants.Multiplicity_Many;

            var proposedEnd1NavPropName = ModelHelper.ConstructProposedNavigationPropertyName(
                pluralizationService, end2Entity.LocalName.Value, end2Multiplicity);
            var end1NavigationPropertyName = ModelHelper.GetUniqueConceptualPropertyName(proposedEnd1NavPropName, end1Entity);
            var proposedEnd2NavPropName    = ModelHelper.ConstructProposedNavigationPropertyName(
                pluralizationService, end1Entity.LocalName.Value, end1Multiplicity);
            var end2NavigationPropertyName = ModelHelper.GetUniqueConceptualPropertyName(
                proposedEnd2NavPropName, end2Entity, new HashSet <string> {
                end1NavigationPropertyName
            });

            var cac = new CreateConceptualAssociationCommand(
                associationName,
                end1Entity, end1Multiplicity, end1NavigationPropertyName,
                end2Entity, end2Multiplicity, end2NavigationPropertyName,
                false,  // uniquify names
                false); // create foreign key properties
            var cp = new CommandProcessor(cpc, cac);

            cp.Invoke();

            return(cac.CreatedAssociation);
        }
        /// <summary>
        ///     Creates a property in the passed in entity of the default Type (non-nullable String).
        ///     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 property</param>
        /// <param name="entityType">The entity to create this property in</param>
        /// <returns>The new Property</returns>
        internal static Property CreateDefaultProperty(CommandProcessorContext cpc, string name, EntityType entityType)
        {
            var cpcd = new CreatePropertyCommand(
                name, entityType, ModelConstants.DefaultPropertyType, ModelConstants.DefaultPropertyNullability);

            cpcd._createWithDefaultName = true;

            var cp = new CommandProcessor(cpc, cpcd);

            cp.Invoke();

            return(cpcd.CreatedProperty);
        }
        internal override void Invoke(CommandProcessorContext cpc)
        {
            var viewModel = _entityType.GetRootViewModel();
            Debug.Assert(viewModel != null, "Unable to find root view model from entity type: " + _entityType.Name);

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

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

                Command c = new EntityDesignRenameCommand(property, _property.Name, true);
                var cp = new CommandProcessor(cpc, c);
                cp.Invoke();
            }
        }
        /// <summary>
        ///     This helper function creates a new entity in the conceptual model that is derived from the
        ///     passed in entity.
        ///     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, derived entity</param>
        /// <param name="baseType">The entity that this new type should derive from</param>
        /// <param name="uniquifyName">Flag whether the name should be checked for uniqueness and then changed as required</param>
        /// <returns>The new EntityType</returns>
        internal static ConceptualEntityType CreateDerivedEntityType(
            CommandProcessorContext cpc, string name, ConceptualEntityType baseType, bool uniquifyName)
        {
            var cet = new CreateEntityTypeCommand(name, uniquifyName);
            var inh = new CreateInheritanceCommand(cet, baseType);

            var cp = new CommandProcessor(cpc, cet, inh);

            cp.Invoke();

            var derivedType = cet.EntityType as ConceptualEntityType;

            Debug.Assert(derivedType != null, "EntityType is not ConceptualEntityType");
            return(derivedType);
        }
Exemple #16
0
        /// <summary>
        ///     Creates a complex property in the passed in entity of the first ComplexType in the model ("Undefined" if there isn't one).
        ///     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>
        /// <param name="name">The name of the new property</param>
        /// <param name="entityType">The entity to create this property in</param>
        /// <returns>The new Complex Property</returns>
        internal static ComplexConceptualProperty CreateDefaultProperty(CommandProcessorContext cpc, string name, EntityType entityType)
        {
            var         model = entityType.EntityModel as ConceptualEntityModel;
            ComplexType type  = null;

            foreach (var complexType in model.ComplexTypes())
            {
                type = complexType;
                break;
            }
            var cpcd = new CreateComplexPropertyCommand(name, entityType, type);

            var cp = new CommandProcessor(cpc, cpcd);

            cp.Invoke();

            return(cpcd.Property);
        }
        /// <summary>
        ///     Creates a new property in the passed in storage entity and optionally sets additional
        ///     facets on the property.
        ///     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 property</param>
        /// <param name="entityType">Must be a storage entity</param>
        /// <param name="type">The type to use for this property (cannot be empty)</param>
        /// <param name="nullable">Flag whether the property is nullable or not</param>
        /// <param name="theDefault">Optional: the default value for this property</param>
        /// <param name="maxLength">Optional facet</param>
        /// <param name="fixedLength">Optional facet</param>
        /// <param name="precision">Optional facet</param>
        /// <param name="scale">Optional facet</param>
        /// <param name="unicode">Optional facet</param>
        /// <param name="collation">Optional facet</param>
        /// <param name="concurrencyMode">Optional: the concurrency mode for this property</param>
        /// <returns>The new Property</returns>
        internal static Property CreateStorageProperty(
            CommandProcessorContext cpc, string name, StorageEntityType entityType,
            string type, bool?nullable, StringOrNone theDefault, StringOrPrimitive <UInt32> maxLength, BoolOrNone fixedLength,
            StringOrPrimitive <UInt32> precision,
            StringOrPrimitive <UInt32> scale, BoolOrNone unicode, StringOrNone collation, string concurrencyMode)
        {
            CommandValidation.ValidateStorageEntityType(entityType);

            var cpcd = new CreatePropertyCommand(name, entityType, type, nullable);
            var ssp  = new SetPropertyFacetsCommand(
                cpcd, theDefault, maxLength, fixedLength, precision, scale, unicode, collation, concurrencyMode);

            var cp = new CommandProcessor(cpc, cpcd, ssp);

            cp.Invoke();

            return(cpcd.CreatedProperty);
        }
        /// <summary>
        ///     Creates a new property in the passed in conceptual entity and optionally sets additional
        ///     facets on the property.
        ///     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 property</param>
        /// <param name="entityType">Must be a conceptual entity</param>
        /// <param name="type">The type to use for this property (cannot be empty)</param>
        /// <param name="nullable">Flag whether the property is nullable or not</param>
        /// <param name="theDefault">Optional: the default value for this property</param>
        /// <param name="concurrencyMode">Optional: the concurrency mode for this property</param>
        /// <param name="getterAccessModifier">Optional: Get access modifier.</param>
        /// <param name="setterAccessModifier">Optional: Set access modifier.</param>
        /// <returns>The new Property</returns>
        internal static Property CreateConceptualProperty(
            CommandProcessorContext cpc, string name, ConceptualEntityType entityType,
            string type, bool?nullable, StringOrNone theDefault, string concurrencyMode, string getterAccessModifier,
            string setterAccessModifier,
            StringOrPrimitive <UInt32> maxLength, bool?fixedLength, StringOrPrimitive <UInt32> precision, StringOrPrimitive <UInt32> scale,
            bool?unicode, StringOrNone collation, string storeGeneratedPattern, InsertPropertyPosition insertPosition)
        {
            CommandValidation.ValidateConceptualEntityType(entityType);

            var cpcd = new CreatePropertyCommand(name, entityType, type, nullable, insertPosition);
            var scp  = new SetConceptualPropertyFacetsCommand(
                cpcd, theDefault, concurrencyMode, getterAccessModifier, setterAccessModifier,
                maxLength, DefaultableValueBoolOrNone.GetFromNullableBool(fixedLength), precision, scale,
                DefaultableValueBoolOrNone.GetFromNullableBool(unicode), collation);
            var scpac = new SetConceptualPropertyAnnotationsCommand(cpcd, storeGeneratedPattern);

            var cp = new CommandProcessor(cpc, cpcd, scp, scpac);

            cp.Invoke();

            return(cpcd.CreatedProperty);
        }
        internal static NavigationProperty CreateDefaultProperty(CommandProcessorContext cpc, string name, ConceptualEntityType entity)
        {
            if (cpc == null)
            {
                throw new ArgumentNullException("cpc");
            }
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException("name");
            }
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }

            var cpcd = new CreateNavigationPropertyCommand(name, entity, null, null, null);

            var cp = new CommandProcessor(cpc, cpcd);
            cp.Invoke();

            return cpcd.NavigationProperty;
        }
Exemple #20
0
        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 static NavigationProperty CreateDefaultProperty(CommandProcessorContext cpc, string name, ConceptualEntityType entity)
        {
            if (cpc == null)
            {
                throw new ArgumentNullException("cpc");
            }
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException("name");
            }
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }

            var cpcd = new CreateNavigationPropertyCommand(name, entity, null, null, null);

            var cp = new CommandProcessor(cpc, cpcd);

            cp.Invoke();

            return(cpcd.NavigationProperty);
        }
        /// <summary>
        ///     Creates a new EntityTypeMapping in the existing EntitySetMapping
        ///     based on another EntityTypeMapping (etmToClone) in a different artifact.
        ///     All the other parameters are presumed to already exist in the same artifact
        ///     as the EntitySetMapping.
        /// </summary>
        internal static EntityTypeMapping CloneEntityTypeMapping(
            CommandProcessorContext cpc,
            EntityTypeMapping etmToClone, EntitySetMapping existingEntitySetMapping,
            ConceptualEntityType existingEntityType, EntityTypeMappingKind kind)
        {
            var createETM = new CreateEntityTypeMappingCommand(existingEntitySetMapping, existingEntityType, kind);
            var cp        = new CommandProcessor(cpc, createETM);

            cp.Invoke();

            var etm = createETM.EntityTypeMapping;

            foreach (var mappingFragment in etmToClone.MappingFragments())
            {
                var sesToClone = mappingFragment.StoreEntitySet.Target as StorageEntitySet;
                var ses        = existingEntitySetMapping.EntityContainerMapping.Artifact.
                                 StorageModel().FirstEntityContainer.GetFirstNamedChildByLocalName(sesToClone.LocalName.Value)
                                 as StorageEntitySet;
                CreateMappingFragmentCommand.CloneMappingFragment(cpc, mappingFragment, etm, ses);
            }

            return(etm);
        }
        /// <summary>
        ///     This helper function creates a new entity in the conceptual model that is derived from the
        ///     passed in entity.
        ///     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, derived entity</param>
        /// <param name="baseType">The entity that this new type should derive from</param>
        /// <param name="uniquifyName">Flag whether the name should be checked for uniqueness and then changed as required</param>
        /// <returns>The new EntityType</returns>
        internal static ConceptualEntityType CreateDerivedEntityType(
            CommandProcessorContext cpc, string name, ConceptualEntityType baseType, bool uniquifyName)
        {
            var cet = new CreateEntityTypeCommand(name, uniquifyName);
            var inh = new CreateInheritanceCommand(cet, baseType);

            var cp = new CommandProcessor(cpc, cet, inh);
            cp.Invoke();

            var derivedType = cet.EntityType as ConceptualEntityType;
            Debug.Assert(derivedType != null, "EntityType is not ConceptualEntityType");
            return derivedType;
        }
        /// <summary>
        ///     Creates complex property with a default,unique name and passed complex type
        /// </summary>
        /// <param name="cpc"></param>
        /// <param name="parentComplexType">parent for new property</param>
        /// <param name="type">type for new property</param>
        /// <returns></returns>
        internal static Property CreateDefaultProperty(CommandProcessorContext cpc, ComplexType parentComplexType, ComplexType type)
        {
            var name = ModelHelper.GetUniqueName(
                typeof(ConceptualProperty), parentComplexType, ComplexConceptualProperty.DefaultComplexPropertyName);
            var cmd = new CreateComplexTypePropertyCommand(name, parentComplexType, type, false);

            var cp = new CommandProcessor(cpc, cmd);
            cp.Invoke();

            return cmd.Property;
        }
        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();
            }
        }
        /// <summary>
        ///     Creates a new MappingFragment in the existing EntityTypeMapping
        ///     based on another MappingFragment (fragToClone) in a different artifact.
        ///     All the other parameters are presumed to already exist in the same artifact
        ///     as the EntityTypeMapping.
        /// </summary>
        internal static MappingFragment CloneMappingFragment(
            CommandProcessorContext cpc, MappingFragment fragToClone,
            EntityTypeMapping existingEntityTypeMapping, StorageEntitySet existingEntitySet)
        {
            var createFragmentCommand = new CreateMappingFragmentCommand(existingEntityTypeMapping, existingEntitySet);
            var cp = new CommandProcessor(cpc, createFragmentCommand);

            cp.Invoke();

            var frag = createFragmentCommand.MappingFragment;

            Debug.Assert(frag != null, "Could not locate or create the required mapping fragment");

            if (frag != null)
            {
                foreach (var sp in fragToClone.ScalarProperties())
                {
                    Property entityProperty = null;
                    if (sp.Name != null &&
                        sp.Name.Target != null &&
                        sp.Name.Target.LocalName != null &&
                        sp.Name.Target.LocalName.Value != null)
                    {
                        entityProperty = ModelHelper.FindPropertyForEntityTypeMapping(
                            existingEntityTypeMapping, sp.Name.Target.LocalName.Value);
                        Debug.Assert(
                            entityProperty != null,
                            "Cannot find Property with name " + sp.Name.Target.LocalName.Value + " for EntityTypeMapping "
                            + existingEntityTypeMapping.ToPrettyString());
                    }

                    Property tableColumn = null;
                    if (frag.StoreEntitySet != null &&
                        frag.StoreEntitySet.Target != null &&
                        frag.StoreEntitySet.Target.EntityType != null &&
                        frag.StoreEntitySet.Target.EntityType.Target != null &&
                        sp.ColumnName != null &&
                        sp.ColumnName.Target != null &&
                        sp.ColumnName.Target.LocalName != null &&
                        sp.ColumnName.Target.LocalName.Value != null)
                    {
                        tableColumn = ModelHelper.FindProperty(
                            frag.StoreEntitySet.Target.EntityType.Target, sp.ColumnName.Target.LocalName.Value);
                        Debug.Assert(
                            tableColumn != null,
                            "Cannot find Property with name " + sp.ColumnName.Target.LocalName.Value + " for EntityType "
                            + frag.StoreEntitySet.Target.EntityType.Target.ToPrettyString());
                    }

                    if (entityProperty != null &&
                        tableColumn != null)
                    {
                        var createScalarCommand = new CreateFragmentScalarPropertyCommand(frag, entityProperty, tableColumn);
                        var cp2 = new CommandProcessor(cpc, createScalarCommand);
                        cp2.Invoke();
                    }
                }
            }

            return(frag);
        }
        /// <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;
        }
        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();
                    }
                }
            }
        }
        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"));
                                });
                    });
        }
        private void ProcessMappingFragment(EntityInfo info, EntityType table, MappingFragment frag)
        {
            // move any scalar mappings to this fragment if they aren't there
            foreach (var sp in info.NonKeyScalars)
            {
                Debug.Assert(sp.ColumnName.Target != null, "Found a ScalarProperty with an unknown column binding");

                if (sp.ColumnName.Target.Parent == table
                    && sp.MappingFragment != frag)
                {
                    // delete the old, create the new
                    AddToDeleteList(sp);

                    var cmd = new CreateFragmentScalarPropertyTreeCommand(frag, sp.GetMappedPropertiesList(), sp.ColumnName.Target);
                    var cp = new CommandProcessor(_cpc, cmd);
                    cp.Invoke();
                }
            }

            // move any conditions to this fragment if they aren't there
            foreach (var cond in info.Conditions)
            {
                Debug.Assert(cond.ColumnName.Target != null, "Found a Condition with an unknown column binding");

                if (cond.ColumnName.Target.Parent == table
                    && cond.MappingFragment != frag)
                {
                    // save off the condition information
                    bool? isNull = null;
                    if (cond.IsNull.Value == Condition.IsNullConstant)
                    {
                        isNull = true;
                    }
                    else if (cond.IsNull.Value == Condition.IsNotNullConstant)
                    {
                        isNull = false;
                    }

                    var conditionValue = cond.Value.Value;
                    var column = cond.ColumnName.Target;

                    // delete the old, create the new
                    AddToDeleteList(cond);

                    var cmd = new CreateFragmentConditionCommand(frag, column, isNull, conditionValue);
                    var cp = new CommandProcessor(_cpc, cmd);
                    cp.Invoke();
                }
            }

            // build a list of all of the keys
            var keysToMap = new List<Property>();
            keysToMap.AddRange(info.KeyProperties);

            // move any key scalar mappings to this fragment if they exist in a different one - provided they are for the same table
            foreach (var sp in info.KeyScalars)
            {
                Debug.Assert(sp.ColumnName.Target != null, "Found a ScalarProperty with an unknown column binding");

                if (sp.ColumnName.Target.Parent == table
                    && sp.MappingFragment != frag)
                {
                    var property = sp.Name.Target;
                    var column = sp.ColumnName.Target;

                    // delete the old, create the new
                    AddToDeleteList(sp);

                    var cmd = new CreateFragmentScalarPropertyCommand(frag, property, column);
                    var cp = new CommandProcessor(_cpc, cmd);
                    cp.Invoke();
                }

                // since we've mapped this one now, remove it from our list of things to do
                keysToMap.Remove(sp.Name.Target);
            }

            // if its TPH, all keys need to be here
            // (Note: if it's not TPH the user needs to specify any missing keys manually)
            if (info.InheritanceStrategy == InheritanceMappingStrategy.TablePerHierarchy)
            {
                // loop through the base most type's keys and add those that we haven't mapped
                foreach (var keyRemaining in keysToMap)
                {
                    var sp = FindKeyMappingInAllParents(info, keyRemaining);
                    if (sp != null
                        && sp.ColumnName.Target != null
                        && sp.ColumnName.Target.Parent == table)
                    {
                        var cmd = new CreateFragmentScalarPropertyCommand(frag, sp.Name.Target, sp.ColumnName.Target);
                        var cp = new CommandProcessor(_cpc, cmd);
                        cp.Invoke();
                    }
                }
            }

            // replicate all non-key base type scalars here if the parent uses a Default ETM
            // (since there is no parent IsTypeOf ETM from which to "inherit" them)
            if (info.Parent != null
                && info.Parent.UsesEntityTypeMappingKind(EntityTypeMappingKind.Default))
            {
                // first gather the list of scalars from all parents
                var parentScalars = new List<ScalarProperty>();
                GatherNonKeyScalarsFromAllParents(info.Parent, parentScalars);

                // then build a list of those scalars used in our fragment
                var existingMappedProperties = new HashSet<Property>();
                foreach (var existingScalar in frag.ScalarProperties())
                {
                    existingMappedProperties.Add(existingScalar.Name.Target);
                }

                // finally, add those in that aren't already in the fragment
                foreach (var sp in parentScalars)
                {
                    Debug.Assert(sp.ColumnName.Target != null, "Found a ScalarProperty with an unknown column binding");

                    // don't duplicate and only add those that use the same table as us
                    if (existingMappedProperties.Contains(sp.Name.Target) == false
                        && sp.ColumnName.Target.EntityType == table)
                    {
                        var cmd = new CreateFragmentScalarPropertyTreeCommand(frag, sp.GetMappedPropertiesList(), sp.ColumnName.Target);
                        var cp = new CommandProcessor(_cpc, cmd);
                        cp.Invoke();

                        existingMappedProperties.Add(sp.Name.Target);
                    }
                }
            }

            // make sure that we don't have any extra scalars
            // so gather the list of all SPs we expect to be here
            var expectedMappedProperties = new List<Property>();
            expectedMappedProperties.AddRange(info.KeyProperties);
            expectedMappedProperties.AddRange(info.NonKeyProperties);
            if (info.Parent != null
                && info.Parent.UsesEntityTypeMappingKind(EntityTypeMappingKind.Default))
            {
                GatherNonKeyPropertiesFromAllParents(info.Parent, expectedMappedProperties);
            }

            // remove any that aren't in our expected list
            foreach (var sp in frag.ScalarProperties())
            {
                if (expectedMappedProperties.Contains(sp.Name.Target) == false)
                {
                    AddToDeleteList(sp);
                }
            }
        }
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            Debug.Assert(cpc != null, "InvokeInternal is called when ExitingFunctionScalarProperty is null.");

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

            if (_propChain == null
                && _pointingNavProp == null
                && _param == null
                && _version != null)
            {
                // setting new version only
                if (string.Compare(_existingFunctionScalarProperty.Version.Value, _version, StringComparison.CurrentCulture) != 0)
                {
                    var mfAncestor = _existingFunctionScalarProperty.GetParentOfType(typeof(ModificationFunction)) as ModificationFunction;
                    Debug.Assert(
                        mfAncestor != null,
                        "Bad attempt to set version on FunctionScalarProperty which does not have a ModificationFunction ancestor");
                    if (mfAncestor != null)
                    {
                        Debug.Assert(
                            mfAncestor.FunctionType == ModificationFunctionType.Update,
                            "Bad attempt to set version on FunctionScalarProperty which has a ModificationFunction ancestor whose FunctionType is "
                            +
                            mfAncestor.FunctionType.ToString() + ". Should be " + ModificationFunctionType.Update.ToString());

                        if (mfAncestor.FunctionType == ModificationFunctionType.Update)
                        {
                            _existingFunctionScalarProperty.Version.Value = _version;
                        }
                    }
                }

                _updatedFunctionScalarProperty = _existingFunctionScalarProperty;
                return;
            }

            // if not just setting version then need to delete and re-create FunctionScalarProperty
            // to allow for changes in properties chain
            // where nulls have been passed in, use existing values (except for _pointingNavProp where null
            // indicates "use no NavProp for the new property")
            var mf = _existingFunctionScalarProperty.GetParentOfType(typeof(ModificationFunction)) as ModificationFunction;
            Debug.Assert(mf != null, "Bad attempt to change FunctionScalarProperty which does not have a ModificationFunction ancestor");
            if (mf == null)
            {
                return;
            }

            var propChain = (_propChain != null ? _propChain : _existingFunctionScalarProperty.GetMappedPropertiesList());
            var parameter = (_param != null ? _param : _existingFunctionScalarProperty.ParameterName.Target);
            var version = (_version != null ? _version : _existingFunctionScalarProperty.Version.Value);

            // now construct delete command for existing FunctionScalarProperty followed by create with new properties
            var cmd1 = _existingFunctionScalarProperty.GetDeleteCommand();
            var cmd2 =
                new CreateFunctionScalarPropertyTreeCommand(mf, propChain, _pointingNavProp, parameter, version);
            cmd2.PostInvokeEvent += (o, eventsArgs) =>
                {
                    _updatedFunctionScalarProperty = cmd2.FunctionScalarProperty;
                    Debug.Assert(
                        _updatedFunctionScalarProperty != null,
                        "CreateFunctionScalarPropertyTreeCommand should not result in null FunctionScalarProperty");
                };

            var cp = new CommandProcessor(cpc, cmd1, cmd2);
            try
            {
                cp.Invoke();
            }
            finally
            {
                _updatedFunctionScalarProperty = null;
            }
        }
        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);
                                });
                    });
        }
Exemple #34
0
        /// <summary>
        ///     Invokes a single command against the CommandProcessor.
        /// </summary>
        internal static void InvokeSingleCommand(CommandProcessorContext cpc, Command cmd)
        {
            var cp = new CommandProcessor(cpc, cmd);

            cp.Invoke();
        }
        internal void ChangeFunctionScalarProperty(EditingContext context, List<Property> newPropertiesChain)
        {
            if (ScalarProperty == null)
            {
                // if we don't have a scalar property, there is nothing to set this into;
                // create the scalar property first
                throw new InvalidOperationException();
            }
            else
            {
                // is the propertiesChain different from what we have already?
                var propertiesChain = ScalarProperty.GetMappedPropertiesList();
                var changeNeeded = false;
                if (propertiesChain.Count != newPropertiesChain.Count)
                {
                    changeNeeded = true;
                }
                else
                {
                    for (var i = 0; i < propertiesChain.Count; i++)
                    {
                        if (propertiesChain[i] != newPropertiesChain[i])
                        {
                            changeNeeded = true;
                            break;
                        }
                    }

                    // if no change needed yet, check NavProp as well
                    if (changeNeeded == false)
                    {
                        // if this property is pointed to by a navigation property, then check if the 
                        // new navigation property is different from the old one
                        if (ScalarProperty.AssociationEnd != null)
                        {
                            var currentNavProp = ModelHelper.FindNavigationPropertyForFunctionScalarProperty(ScalarProperty);
                            // currentNavProp can be null if the NavProp has been deleted
                            changeNeeded = (currentNavProp == null ? true : (currentNavProp != _pointingNavProperty));
                        }
                        else
                        {
                            // the previous property was not pointed to by a navigation property but the new one is
                            if (_pointingNavProperty != null)
                            {
                                changeNeeded = true;
                            }
                        }
                    }
                }

                if (changeNeeded)
                {
                    // delete old and create new FunctionScalarProperty in one transaction - this takes care of
                    // removing any old ComplexProperty or AssociationEnd parent nodes as necessary
                    var cpc = new CommandProcessorContext(
                        context, EfiTransactionOriginator.MappingDetailsOriginatorId, Resources.Tx_ChangeScalarProperty);
                    var version = (ScalarProperty.Version == null ? null : ScalarProperty.Version.Value);
                    // Version is used only for Update ModificationFunctions
                    var cmd = new ChangeFunctionScalarPropertyCommand(
                        ScalarProperty, newPropertiesChain, _pointingNavProperty, StoreParameter, version);
                    cmd.PostInvokeEvent += (o, eventsArgs) =>
                        {
                            var fsp = cmd.FunctionScalarProperty;
                            Debug.Assert(fsp != null, "ChangeFunctionScalarPropertyCommand failed to create a FunctionScalarProperty");
                            ModelItem = fsp;
                        };

                    var cp = new CommandProcessor(cpc, cmd);
                    try
                    {
                        cp.Invoke();
                    }
                    catch
                    {
                        ModelItem = null;

                        throw;
                    }
                }
            }
        }
        /// <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;
        }
        // <summary>
        //     The mapping view model contains a MappingEndScalarProperty for every key in each end.  The user can clear out the
        //     underlying scalar property, but that doesn't remove or add the MappingEndScalarProperty.  We need the placeholder
        //     in the view model to show the nodes in the Trid even if there isn't a mapping.  Thus, we don't need to call
        //     this.Parent.AddChild(this) since its already there.
        // </summary>
        internal override void CreateModelItem(CommandProcessorContext cpc, EditingContext context, EFElement underlyingModelItem)
        {
            Debug.Assert(underlyingModelItem != null, "The underlyingModelItem cannot be null");
            var tableColumn = underlyingModelItem as Property;
            Debug.Assert(context != null, "The context argument cannot be null");
            Debug.Assert(ScalarProperty == null, "Don't call this method if we already have a ModelItem");
            Debug.Assert(tableColumn != null, "The tableColumn cannot be null.");
            if (tableColumn == null)
            {
                return;
            }
            Debug.Assert(tableColumn.EntityType.EntityModel.IsCSDL == false, "tableColumn must be a Store-side Property");

            Context = context;

            // find the c-side property based on the passed in name
            var entityProperty = MappingAssociationSetEnd.ConceptualEntityType.GetFirstNamedChildByLocalName(Property) as Property;
            if (entityProperty == null)
            {
                // they might be trying to map a key from the base class
                EntityType topMostBaseType = MappingAssociationSetEnd.ConceptualEntityType.ResolvableTopMostBaseType;
                entityProperty = topMostBaseType.GetFirstNamedChildByLocalName(Property) as Property;
            }
            Debug.Assert(entityProperty != null, "Failed looking up entity property for ScalarProperty.");
            if (entityProperty == null)
            {
                return;
            }

            // create our context if we don't have one
            if (cpc == null)
            {
                cpc = new CommandProcessorContext(
                    Context, EfiTransactionOriginator.MappingDetailsOriginatorId, Resources.Tx_CreateScalarProperty);
            }

            // create the right command
            CreateEndScalarPropertyCommand cmd = null;
            var end = MappingAssociationSetEnd.AssociationSetEnd.EndProperty;
            if (end == null)
            {
                // we don't have an end yet, this version will create an end as well as the scalar property
                cmd = new CreateEndScalarPropertyCommand(
                    MappingAssociationSet.AssociationSet.AssociationSetMapping, MappingAssociationSetEnd.AssociationSetEnd, entityProperty,
                    tableColumn);
            }
            else
            {
                cmd = new CreateEndScalarPropertyCommand(end, entityProperty, tableColumn);
            }

            // set up our post event to fix up the view model
            cmd.PostInvokeEvent += (o, eventArgs) =>
                {
                    var sp = cmd.ScalarProperty;
                    Debug.Assert(sp != null, "cmd failed to generate ScalarProperty");

                    // fix up our view model (we don't have to add this to the parent's children collection
                    // because we created a placeholder row already for every key in the entity)
                    ModelItem = sp;
                };

            try
            {
                // now make the change
                var cp = new CommandProcessor(cpc, cmd);
                cp.Invoke();
            }
            catch
            {
                ModelItem = null;
                throw;
            }
        }
        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;
            }
        }
        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;
            }
        }
        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;
        }
Exemple #41
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 override void CreateModelItem(CommandProcessorContext cpc, EditingContext context, EFElement underlyingModelItem)
        {
            Debug.Assert(context != null, "context must not be null");
            Debug.Assert(Condition == null, "Don't call this method if we already have a ModelItem");
            Debug.Assert(MappingStorageEntityType.StorageEntityType != null, "The parent item isn't set up correctly");
            Debug.Assert(underlyingModelItem != null, "underlyingModelItem must not be null");

            var tableColumn = underlyingModelItem as Property;
            Debug.Assert(
                tableColumn != null, "underlyingModelItem must be of type Property, actual type = " + underlyingModelItem.GetType().FullName);

            // store this off in case we have recover the condition later (if it moves to another ETM on us)
            _modelItemColumnName = tableColumn.LocalName.Value;

            Context = context;

            // local shortcuts
            EntityType entityType = MappingConceptualEntityType.ConceptualEntityType;

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

            // use empty string as a default condition value
            var cmd = new CreateFragmentConditionCommand(entityType, tableColumn, null, String.Empty);

            // set up our post event to fix up the view model
            cmd.PostInvokeEvent += (o, eventsArgs) =>
                {
                    var cond = cmd.CreatedCondition;
                    Debug.Assert(cond != null, "cmd failed to create Condition");

                    // fix up our view model
                    ModelItem = cond;
                    Parent.AddChild(this);
                };

            try
            {
                // now make the change
                var cp = new CommandProcessor(cpc, cmd);
                cp.Invoke();
            }
            catch
            {
                ModelItem = null;
                Parent.RemoveChild(this);

                throw;
            }
        }
        internal void ChangeScalarProperty(EditingContext context, List<Property> newPropertiesChain)
        {
            if (ModelItem != null)
            {
                var propertiesChain = ScalarProperty.GetMappedPropertiesList();
                var changeNeeded = false;
                // is it different than what we have already?
                if (propertiesChain.Count != newPropertiesChain.Count)
                {
                    changeNeeded = true;
                }
                else
                {
                    for (var i = 0; i < propertiesChain.Count; i++)
                    {
                        if (propertiesChain[i] != newPropertiesChain[i])
                        {
                            changeNeeded = true;
                            break;
                        }
                    }
                }

                if (changeNeeded)
                {
                    Debug.Assert(ScalarProperty.ColumnName.Status == BindingStatus.Known, "Table column not found");
                    if (ScalarProperty.ColumnName.Status == BindingStatus.Known)
                    {
                        // delete old and create new ScalarProperty in one transaction
                        var cpc = new CommandProcessorContext(
                            context, EfiTransactionOriginator.MappingDetailsOriginatorId, Resources.Tx_ChangeScalarProperty);
                        var cmd1 = ScalarProperty.GetDeleteCommand();
                        var cmd2 = new CreateFragmentScalarPropertyTreeCommand(
                            MappingConceptualEntityType.ConceptualEntityType, newPropertiesChain, ScalarProperty.ColumnName.Target);
                        cmd2.PostInvokeEvent += (o, eventsArgs) =>
                            {
                                var sp = cmd2.ScalarProperty;
                                Debug.Assert(sp != null, "CreateFragmentScalarPropertyTreeCommand falied to create a ScalarProperty");
                                ModelItem = sp;
                            };

                        var cp = new CommandProcessor(cpc, cmd1, cmd2);
                        try
                        {
                            cp.Invoke();
                        }
                        catch
                        {
                            ModelItem = null;

                            throw;
                        }
                    }
                }
            }
            else
            {
                // if we don't have a scalar property, there is nothing to set this into;
                // create the scalar property first
                throw new InvalidOperationException();
            }
        }
        // <summary>
        //     The mapping view model contains a MappingFunctionScalarProperty for every parameter in the function.  The user can clear out the
        //     underlying scalar property, but that doesn't remove or add the MappingFunctionScalarProperty.  We need the placeholder
        //     in the view model to show the nodes in the Trid even if there isn't a mapping.  Thus, we don't need to call
        //     this.Parent.AddChild(this) since its already there.
        // </summary>
        internal void CreateModelItem(CommandProcessorContext cpc, EditingContext context, List<Property> propertiesChain)
        {
            Debug.Assert(propertiesChain != null, "The propertiesChain cannot be null");
            Debug.Assert(context != null, "The context argument cannot be null");
            Debug.Assert(ScalarProperty == null, "Don't call this method if we already have a ModelItem");
            Debug.Assert(MappingModificationFunctionMapping.Function != null, "The parent item isn't set up correctly");

            if (propertiesChain == null
                || context == null
                || ScalarProperty != null
                || MappingModificationFunctionMapping == null)
            {
                return;
            }

            Debug.Assert(propertiesChain.Count > 0, "propertiesChain cannot be empty");
            if (propertiesChain.Count <= 0)
            {
                return;
            }

            Context = context;

            var mf = MappingModificationFunctionMapping.ModificationFunction;
            if (null == mf)
            {
                Debug.Fail("this.MappingModificationFunctionMapping.ModificationFunction is null");
                return;
            }

            // use the stored Parameter
            var parameter = StoreParameter;
            if (parameter == null)
            {
                return;
            }

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

            // create the FunctionScalarProperty command (including any intermediate ComplexProperty's or AssociationEnd's)
            var version = (MappingModificationFunctionMapping.ModificationFunctionType == ModificationFunctionType.Update
                               ? ModelConstants.FunctionScalarPropertyVersionCurrent
                               : null);
            var cmd =
                new CreateFunctionScalarPropertyTreeCommand(mf, propertiesChain, _pointingNavProperty, parameter, version);

            // set up our post event to fix up the view model
            cmd.PostInvokeEvent += (o, eventsArgs) =>
                {
                    var fsp = cmd.FunctionScalarProperty;
                    Debug.Assert(fsp != null, "CreateFunctionScalarPropertyTreeCommand did not create a FunctionScalarProperty");

                    // fix up our view model (we don't have to add this to the parent's children collection
                    // because we created a placeholder row already for every parameter in the function)
                    ModelItem = fsp;
                };

            try
            {
                // now make the change
                var cp = new CommandProcessor(cpc, cmd);
                cp.Invoke();
            }
            catch
            {
                ModelItem = null;
                throw;
            }
        }
        // <summary>
        //     The mapping view model contains a MappingScalarProperty for every column in the table.  The user can clear out the
        //     underlying scalar property, but that doesn't remove or add the MappingScalarProperty.  We need the placeholder
        //     in the view model to show the nodes in the Trid even if there isn't a mapping.  Thus, we don't need to call
        //     this.Parent.AddChild(this) since its already there.
        // </summary>
        internal void CreateModelItem(CommandProcessorContext cpc, EditingContext context, List<Property> propertiesChain)
        {
            Debug.Assert(propertiesChain != null, "The propertiesChain cannot be null");
            Debug.Assert(context != null, "The context argument cannot be null");
            Debug.Assert(ScalarProperty == null, "Don't call this method if we already have a ModelItem");
            Debug.Assert(MappingStorageEntityType.StorageEntityType != null, "The parent item isn't set up correctly");

            Debug.Assert(propertiesChain.Count > 0, "propertiesChain cannot be empty");

            Context = context;

            // local shortcuts
            EntityType entityType = MappingConceptualEntityType.ConceptualEntityType;
            EntityType table = MappingStorageEntityType.StorageEntityType;

            // find the s-side property based on the value stored in this.ColumnName
            var tableColumn = table.GetFirstNamedChildByLocalName(ColumnName) as Property;
            Debug.Assert(tableColumn != null, "Failed looking up table column for ScalarProperty.");
            if (tableColumn == null)
            {
                return;
            }

            try
            {
                // now make the change
                if (cpc == null)
                {
                    cpc = new CommandProcessorContext(
                        Context, EfiTransactionOriginator.MappingDetailsOriginatorId, Resources.Tx_CreateScalarProperty);
                }
                var cmd = new CreateFragmentScalarPropertyTreeCommand(entityType, propertiesChain, tableColumn);
                cmd.PostInvokeEvent += (o, eventsArgs) =>
                    {
                        var sp = cmd.ScalarProperty;
                        Debug.Assert(sp != null, "CreateFragmentScalarPropertyTreeCommand failed to create ScalarProperty");

                        // fix up our view model (we don't have to add this to the parent's children collection
                        // because we created a placeholder row already for every column in the table)
                        ModelItem = sp;
                    };

                var cp = new CommandProcessor(cpc, cmd);
                cp.Invoke();
            }
            catch
            {
                ModelItem = null;

                throw;
            }
        }
Exemple #46
0
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            var artifact = cpc.EditingContext.GetEFArtifactService().Artifact;

            if (null == artifact)
            {
                Debug.Fail("null artifact not allowed");
                return;
            }

            // safety check, this should never be hit
            Debug.Assert(_schemaProcedure != null, "InvokeInternal is called when _schemaProcedure is null");
            if (null == _schemaProcedure)
            {
                throw new InvalidOperationException("InvokeInternal is called when _schemaProcedure is null.");
            }

            var cModel = artifact.ConceptualModel();

            if (null == cModel)
            {
                Debug.Fail("ConceptualEntityModel not allowed");
                return;
            }

            var cContainer = cModel.FirstEntityContainer as ConceptualEntityContainer;

            if (null == cContainer)
            {
                Debug.Fail("ConceptualEntityContainer not allowed");
                return;
            }

            var sModel = artifact.StorageModel();

            if (null == sModel)
            {
                Debug.Fail("null StorageEntityModel not allowed");
                return;
            }

            // determine matching Function
            var funcObj  = DatabaseObject.CreateFromSchemaProcedure(_schemaProcedure);
            var function = ModelHelper.FindFunction(sModel, funcObj);

            if (null == function)
            {
                // in some error scenarios where the model has not been properly created we can be asked to create a FunctionImport for a Function which does not exist
                // if so just return without creating
                return;
            }

            // do not produce FunctionImports for composable Functions unless _shouldCreateComposableFunctionImport is true
            if (false == _shouldCreateComposableFunctionImport &&
                function.IsComposable.Value)
            {
                return;
            }

            // determine FunctionImport name and make sure it is unique
            var functionImportName = OverrideNameValue;

            if (String.IsNullOrWhiteSpace(functionImportName))
            {
                if (null == function.LocalName ||
                    string.IsNullOrEmpty(function.LocalName.Value))
                {
                    Debug.Fail("null or empty LocalName attribute for matching Function " + function);
                    return;
                }
                functionImportName = ModelHelper.GetUniqueName(typeof(FunctionImport), cContainer, function.LocalName.Value);
            }
            else
            {
#if DEBUG
                string errorMessage;
                var    isUnique = ModelHelper.IsUniqueName(typeof(FunctionImport), cContainer, functionImportName, false, out errorMessage);
                Debug.Assert(isUnique, "If we gave CreateMatchingFunctionImportCommand a name, it should have been unique");
#endif
            }

            object      returnType = null;
            ComplexType existingComplexTypeReturnType = null;
            if (OverrideReturnTypeValue == null)
            {
                // get return type of the Function
                returnType = ConstructReturnType(_schemaProcedure, cModel, sModel, functionImportName);
                if (null == returnType)
                {
                    Debug.Fail("cannot determine return type for schemaProcedure " + _schemaProcedure);
                    return;
                }
            }
            else
            {
                if (OverrideReturnTypeValue.Equals(ModelConstants.NoneValue, StringComparison.Ordinal))
                {
                    returnType = Resources.NoneDisplayValueUsedForUX;
                }
                else
                {
                    var rawValue = ModelHelper.UnwrapCollectionAroundFunctionImportReturnType(OverrideReturnTypeValue);

                    // Here we attempt to find the corresponding ReturnType for the given ReturnTypeOverride.
                    // The ReturnTypeOverride will be specified as the actual XAttribute value of the return type
                    if (OverrideEntitySetValue != null)
                    {
                        if (ModelHelper.FindEntitySet(cpc.Artifact.ConceptualModel(), OverrideEntitySetValue) != null)
                        {
                            // ReturnType is an EntityType
                            returnType = ModelHelper.FindEntityTypeViaSymbol(cpc.Artifact.ConceptualModel(), rawValue);
                        }
                    }
                    else if (!ModelHelper.AllPrimitiveTypes(artifact.SchemaVersion).Contains(rawValue))
                    {
                        // ReturnType is a ComplexType
                        existingComplexTypeReturnType = ModelHelper.FindComplexType(cpc.Artifact.ConceptualModel(), rawValue);
                        returnType = existingComplexTypeReturnType;
                    }
                    else
                    {
                        returnType = rawValue;
                    }
                }
            }

            // Composable functions that do not return collections (e.g. scalar valued functions) are not supported
            // and should not be imported to the conceptual model
            if (Resources.NoneDisplayValueUsedForUX.Equals(returnType) &&
                function.IsComposable.Value)
            {
                return;
            }

            // list of commands to be executed
            IList <Command> commands = new List <Command>();

            // if return type is the name of a ComplexType then create a new matching ComplexType
            CreateComplexTypeCommand createComplexTypeCommand = null;
            if (OverrideReturnTypeValue == null &&
                returnType is string &&
                false == Resources.NoneDisplayValueUsedForUX.Equals(returnType))
            {
                createComplexTypeCommand = AddCreateComplexTypeCommands(sModel, returnType as string, _schemaProcedure.RawColumns, commands);
            }

            // if we created a ComplexType above then pass that as a pre-req to the CreateFunctionImport command,
            // otherwise just create the FunctionImport without the pre-req
            CreateFunctionImportCommand cmdFuncImp;
            if (createComplexTypeCommand == null)
            {
                if (returnType is EdmType)
                {
                    // For the case where the FunctionImport should have a return type which is not a Complex Type but
                    // simply a C-side primitive type we have to pass the _name_ of the C-side primitive type to
                    // CreateFunctionImportCommand, rather than the type itself
                    returnType = (returnType as EdmType).Name;
                }
                cmdFuncImp = new CreateFunctionImportCommand(cContainer, function, functionImportName, returnType);
            }
            else
            {
                cmdFuncImp = new CreateFunctionImportCommand(cContainer, function, functionImportName, createComplexTypeCommand);
            }

            commands.Add(cmdFuncImp);

            // now create the FunctionImportMapping to map the S-side Function to the C-side FunctionImport
            if (null != artifact.MappingModel() &&
                null != artifact.MappingModel().FirstEntityContainerMapping)
            {
                var cmdFuncImpMapping = new CreateFunctionImportMappingCommand(
                    artifact.MappingModel().FirstEntityContainerMapping, function, cmdFuncImp.Id);
                cmdFuncImpMapping.AddPreReqCommand(cmdFuncImp);
                commands.Add(cmdFuncImpMapping);

                IDictionary <string, string> mapPropertyNameToColumnName = null;
                if (_schemaProcedure != null)
                {
                    mapPropertyNameToColumnName =
                        ModelHelper.ConstructComplexTypePropertyNameToColumnNameMapping(
                            _schemaProcedure.RawColumns.Select(c => c.Name).ToList());
                }

                // Create explicit function-import result type mapping if the return type is a complex type.
                if (createComplexTypeCommand != null)
                {
                    commands.Add(
                        new CreateFunctionImportTypeMappingCommand(cmdFuncImpMapping, createComplexTypeCommand)
                    {
                        CreateDefaultScalarProperties = true,
                        PropertyNameToColumnNameMap   = mapPropertyNameToColumnName
                    });
                }
                else if (OverrideReturnTypeValue != null &&
                         existingComplexTypeReturnType != null)
                {
                    commands.Add(
                        new CreateFunctionImportTypeMappingCommand(cmdFuncImpMapping, existingComplexTypeReturnType)
                    {
                        CreateDefaultScalarProperties = true,
                        PropertyNameToColumnNameMap   = mapPropertyNameToColumnName
                    });
                }
            }

            // now invoke the list of commands
            if (null != commands)
            {
                var cp = new CommandProcessor(cpc, commands);
                cp.Invoke();

                // assign the generated FunctionImport so this command can be used as input for others
                _generatedFunctionImport = cmdFuncImp.FunctionImport;
            }
        }
        // <summary>
        //     This lets you switch the underlyingModelItem.
        // </summary>
        // <param name="cpc">The transaction to use for this entire process, cannot be null</param>
        // <param name="context">The current EditingContext</param>
        // <param name="newUnderlyingModelItem">The new model item to switch to</param>
        // <param name="deleteModelItemOnly">If 'true' then the MappingEFElement will just have its model item switched, if 'false' then a new MappingEFElement will be create and this one will be deleted</param>
        internal void SwitchModelItem(
            CommandProcessorContext cpc, EditingContext context, EFElement newUnderlyingModelItem, bool deleteModelItemOnly)
        {
            Debug.Assert(cpc != null, "You should send a cpc to this function so that the entire switch is in a single transaction");

            var cmd = new DelegateCommand(
                () =>
                    {
                        if (deleteModelItemOnly)
                        {
                            DeleteModelItemsRecursive(this, cpc);
                            CreateModelItem(cpc, context, newUnderlyingModelItem);
                        }
                        else
                        {
                            Delete(cpc);
                            var newElement = CreateCreatorNodeCopy();
                            newElement.CreateModelItem(cpc, context, newUnderlyingModelItem);
                        }
                    });

            var cp = new CommandProcessor(cpc, cmd);
            cp.Invoke();
        }
 /// <summary>
 ///     Invokes a single command against the CommandProcessor.
 /// </summary>
 internal static void InvokeSingleCommand(CommandProcessorContext cpc, Command cmd)
 {
     var cp = new CommandProcessor(cpc, cmd);
     cp.Invoke();
 }
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            Debug.Assert(cpc != null, "InvokeInternal is called when ExitingFunctionScalarProperty is null.");

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

            if (_propChain == null &&
                _pointingNavProp == null &&
                _param == null &&
                _version != null)
            {
                // setting new version only
                if (string.Compare(_existingFunctionScalarProperty.Version.Value, _version, StringComparison.CurrentCulture) != 0)
                {
                    var mfAncestor = _existingFunctionScalarProperty.GetParentOfType(typeof(ModificationFunction)) as ModificationFunction;
                    Debug.Assert(
                        mfAncestor != null,
                        "Bad attempt to set version on FunctionScalarProperty which does not have a ModificationFunction ancestor");
                    if (mfAncestor != null)
                    {
                        Debug.Assert(
                            mfAncestor.FunctionType == ModificationFunctionType.Update,
                            "Bad attempt to set version on FunctionScalarProperty which has a ModificationFunction ancestor whose FunctionType is "
                            +
                            mfAncestor.FunctionType.ToString() + ". Should be " + ModificationFunctionType.Update.ToString());

                        if (mfAncestor.FunctionType == ModificationFunctionType.Update)
                        {
                            _existingFunctionScalarProperty.Version.Value = _version;
                        }
                    }
                }

                _updatedFunctionScalarProperty = _existingFunctionScalarProperty;
                return;
            }

            // if not just setting version then need to delete and re-create FunctionScalarProperty
            // to allow for changes in properties chain
            // where nulls have been passed in, use existing values (except for _pointingNavProp where null
            // indicates "use no NavProp for the new property")
            var mf = _existingFunctionScalarProperty.GetParentOfType(typeof(ModificationFunction)) as ModificationFunction;

            Debug.Assert(mf != null, "Bad attempt to change FunctionScalarProperty which does not have a ModificationFunction ancestor");
            if (mf == null)
            {
                return;
            }

            var propChain = (_propChain != null ? _propChain : _existingFunctionScalarProperty.GetMappedPropertiesList());
            var parameter = (_param != null ? _param : _existingFunctionScalarProperty.ParameterName.Target);
            var version   = (_version != null ? _version : _existingFunctionScalarProperty.Version.Value);

            // now construct delete command for existing FunctionScalarProperty followed by create with new properties
            var cmd1 = _existingFunctionScalarProperty.GetDeleteCommand();
            var cmd2 =
                new CreateFunctionScalarPropertyTreeCommand(mf, propChain, _pointingNavProp, parameter, version);

            cmd2.PostInvokeEvent += (o, eventsArgs) =>
            {
                _updatedFunctionScalarProperty = cmd2.FunctionScalarProperty;
                Debug.Assert(
                    _updatedFunctionScalarProperty != null,
                    "CreateFunctionScalarPropertyTreeCommand should not result in null FunctionScalarProperty");
            };

            var cp = new CommandProcessor(cpc, cmd1, cmd2);

            try
            {
                cp.Invoke();
            }
            finally
            {
                _updatedFunctionScalarProperty = null;
            }
        }
        internal void CreateModelItem(CommandProcessorContext cpc, EditingContext context, string columnName)
        {
            Debug.Assert(context != null, "The context argument cannot be null");
            Debug.Assert(ScalarProperty == null, "Don't call this method if we already have a ModelItem");
            Debug.Assert(_property != null, "The _property cannot be null.");
            Debug.Assert(
                MappingFunctionImport.FunctionImport != null && MappingFunctionImport.FunctionImportMapping != null,
                "The parent item isn't set up correctly");

            Context = context;
            var fi = MappingFunctionImport.FunctionImport;
            var fim = MappingFunctionImport.FunctionImportMapping;
            if (_property != null
                && fi != null
                && fim != null)
            {
                // get the ReturnType of the FunctionImport
                EntityType entityType = null;
                ComplexType complexType = null;
                if (fi.IsReturnTypeEntityType)
                {
                    entityType = fi.ReturnTypeAsEntityType.Target;
                }
                else if (fi.IsReturnTypeComplexType
                         && fi.ReturnTypeAsComplexType.Target != null)
                {
                    complexType = fi.ReturnTypeAsComplexType.Target;
                }

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

                // first we need to create a FunctionImportTypeMapping element (either EntityTypeMapping or ComplexTypeMapping)
                var cmd = entityType != null
                              ? new CreateFunctionImportTypeMappingCommand(MappingFunctionImport.FunctionImportMapping, entityType)
                              : new CreateFunctionImportTypeMappingCommand(MappingFunctionImport.FunctionImportMapping, complexType);

                // create the ScalarProperty
                var cmd2 = new CreateFunctionImportScalarPropertyCommand(cmd, _property, columnName);
                // set up our post event to fix up the view model
                cmd2.PostInvokeEvent += (o, eventsArgs) =>
                    {
                        var sp = cmd2.ScalarProperty;
                        Debug.Assert(sp != null, "Didn't get good ScalarProperty out of the command");

                        // fix up our view model (we don't have to add this to the parent's children collection
                        // because we created a placeholder row already for each property)
                        ModelItem = sp;
                    };

                // now make the change
                var cp = new CommandProcessor(cpc, cmd, cmd2);
                cp.Invoke();
            }
        }