public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
        {
            if (context == null
                || context.Instance == null)
            {
                return value;
            }

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

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

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

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

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

                // go create it
                var cp = new CommandProcessor(cpc);
                var cmd = new CreateDiagramCommand(diagramName, entityDesignArtifact.DesignerInfo.Diagrams);
                cp.EnqueueCommand(cmd);
                cp.Invoke();
                return cmd.Diagram;
            }
            return null;
        }
        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);
                        }
                    }
                }
            }
        }
        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();
            }
        }
        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;
        }
        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;
        }
        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();
            }
        }
Exemple #10
0
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            // safety check, this should never be hit
            Debug.Assert(
                _conceptualEntityType != null && _function != null,
                "InvokeInternal is called when _conceptualEntityType or _function is null");
            if (_conceptualEntityType == null ||
                _function == null)
            {
                throw new InvalidOperationException("InvokeInternal is called when _conceptualEntityType or _function is null");
            }

            // see if we have the ETM we need, if not create it
            var entityTypeMapping = ModelHelper.FindEntityTypeMapping(
                cpc,
                _conceptualEntityType,
                EntityTypeMappingKind.Function,
                true);

            Debug.Assert(entityTypeMapping != null, "Failed to create the EntityTypeMapping to house this item");
            if (entityTypeMapping == null)
            {
                throw new ParentItemCreationFailureException();
            }

            // if we created a new ETM, then we'll need to also create the ModificationFunctionMapping
            if (entityTypeMapping.ModificationFunctionMapping == null)
            {
                entityTypeMapping.ModificationFunctionMapping = new ModificationFunctionMapping(entityTypeMapping, null);
                XmlModelHelper.NormalizeAndResolve(entityTypeMapping.ModificationFunctionMapping);
            }
            Debug.Assert(
                entityTypeMapping.ModificationFunctionMapping != null,
                "Failed to create the ModificationFunctionMapping node to house this item");
            if (entityTypeMapping.ModificationFunctionMapping == null)
            {
                throw new ParentItemCreationFailureException();
            }

            // now go and actually create the item
            if (_type == ModificationFunctionType.Insert)
            {
                _modificationFunction = new InsertFunction(entityTypeMapping.ModificationFunctionMapping, null);
                entityTypeMapping.ModificationFunctionMapping.InsertFunction = _modificationFunction as InsertFunction;
            }
            else if (_type == ModificationFunctionType.Update)
            {
                _modificationFunction = new UpdateFunction(entityTypeMapping.ModificationFunctionMapping, null);
                entityTypeMapping.ModificationFunctionMapping.UpdateFunction = _modificationFunction as UpdateFunction;
            }
            else if (_type == ModificationFunctionType.Delete)
            {
                _modificationFunction = new DeleteFunction(entityTypeMapping.ModificationFunctionMapping, null);
                entityTypeMapping.ModificationFunctionMapping.DeleteFunction = _modificationFunction as DeleteFunction;
            }
            Debug.Assert(_modificationFunction != null, "Failed to create the new function mapping");
            if (_modificationFunction == null)
            {
                throw new ItemCreationFailureException();
            }

            // set the function into the function mapping
            _modificationFunction.FunctionName.SetRefName(_function);

            // set the RowsAffectedParameter
            var cmd = new SetRowsAffectedParameterCommand(_modificationFunction, _rowsAffectedParameter);

            CommandProcessor.InvokeSingleCommand(cpc, cmd);

            XmlModelHelper.NormalizeAndResolve(_modificationFunction);
        }
Exemple #11
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();
        }
        /// <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);
        }
        private void CopyAssociation(
            CommandProcessorContext cpc, BaseEntityModel model, AssociationClipboardFormat clipboardAssociation
            , Dictionary <EntityTypeClipboardFormat, EntityType> entitiesMap)
        {
            var associationName  = ModelHelper.GetUniqueName(typeof(Association), model, clipboardAssociation.AssociationName);
            var clipboardEntity1 = clipboardAssociation.ClipboardEntity1;
            var clipboardEntity2 = clipboardAssociation.ClipboardEntity2;

            var entity1 = entitiesMap[clipboardEntity1] as ConceptualEntityType;
            var entity2 = entitiesMap[clipboardEntity2] as ConceptualEntityType;

            Debug.Assert(entity1 != null, "entity1 is not a ConceptualEntityType");
            Debug.Assert(entity2 != null, "entity2 is not a ConceptualEntityType");

            var navigationPropertyEntity1 = clipboardEntity1.GetNavigationPropertyClipboard(
                clipboardAssociation.AssociationName, clipboardAssociation.AssociationEndRole1);
            var navigationPropertyEntity2 = clipboardEntity2.GetNavigationPropertyClipboard(
                clipboardAssociation.AssociationName, clipboardAssociation.AssociationEndRole2);

            var navigationPropertyName1 = navigationPropertyEntity1 != null
                                              ? ModelHelper.GetUniqueConceptualPropertyName(navigationPropertyEntity1.PropertyName, entity1)
                                              : null;

            string navigationPropertyName2 = null;

            if (entity1 == entity2)
            {
                // if this is a self-association then the NavProp for end2 needs a different name from end1
                navigationPropertyName2 =
                    ModelHelper.GetUniqueConceptualPropertyName(
                        (navigationPropertyEntity2 != null ? navigationPropertyEntity2.PropertyName : entity1.LocalName.Value), entity2,
                        new HashSet <string> {
                    navigationPropertyName1
                });
            }
            else
            {
                navigationPropertyName2 =
                    ModelHelper.GetUniqueConceptualPropertyName(
                        (navigationPropertyEntity2 != null ? navigationPropertyEntity2.PropertyName : entity1.LocalName.Value), entity2);
            }
            var cmd = new CreateConceptualAssociationCommand(
                associationName, entity1, clipboardAssociation.Multiplicity1, navigationPropertyName1, entity2,
                clipboardAssociation.Multiplicity2, navigationPropertyName2, true, false);

            CommandProcessor.InvokeSingleCommand(cpc, cmd);

            // copy nav prop facets & structured annotations
            if (navigationPropertyEntity1 != null)
            {
                var np1 = entity1.FindNavigationPropertyForEnd(cmd.End1);
                CommandProcessor.InvokeSingleCommand(
                    cpc,
                    new SetNavigationPropertyFacetsCommand(
                        np1, navigationPropertyEntity1.GetterAccessModifier, navigationPropertyEntity1.SetterAccessModifier));
                AddAnnotations(navigationPropertyEntity1, np1);
            }
            if (navigationPropertyEntity2 != null)
            {
                var np2 = entity2.FindNavigationPropertyForEnd(cmd.End2);
                CommandProcessor.InvokeSingleCommand(
                    cpc,
                    new SetNavigationPropertyFacetsCommand(
                        np2, navigationPropertyEntity2.GetterAccessModifier, navigationPropertyEntity2.SetterAccessModifier));
                AddAnnotations(navigationPropertyEntity2, np2);
            }

            if (clipboardAssociation.ReferentialConstraint != null)
            {
                EntityType principal;
                EntityType dependent;
                if (entity1 == FindEntityByClipboardName(clipboardAssociation.ReferentialConstraint.PrincipalEntityName, entitiesMap))
                {
                    principal = entity1;
                    dependent = entity2;
                }
                else
                {
                    Debug.Assert(
                        entity2 == FindEntityByClipboardName(clipboardAssociation.ReferentialConstraint.PrincipalEntityName, entitiesMap),
                        "could not find entity using clipboard name " + clipboardAssociation.ReferentialConstraint.PrincipalEntityName);

                    principal = entity2;
                    dependent = entity1;
                }
                IEnumerable <Property> principalPropertyList = null;
                IEnumerable <Property> dependentPropertyList = null;
                var associationEnds = cmd.CreatedAssociation.AssociationEnds();
                if (associationEnds.Count == 2 &&
                    (principalPropertyList =
                         ModelHelper.FindProperties(principal, clipboardAssociation.ReferentialConstraint.PrincipalProperties)) != null &&
                    (dependentPropertyList =
                         ModelHelper.FindProperties(dependent, clipboardAssociation.ReferentialConstraint.DependentProperties)) != null)
                {
                    var refCmd = new CreateReferentialConstraintCommand(
                        associationEnds[0], associationEnds[1], principalPropertyList, dependentPropertyList
                        );
                    CommandProcessor.InvokeSingleCommand(cpc, refCmd);
                    AddAnnotations(clipboardAssociation.ReferentialConstraint, refCmd.ReferentialConstraint);
                }
            }

            // add structured annotations to the association
            AddAnnotations(clipboardAssociation, cmd.CreatedAssociation);
        }
 /// <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)
        {
            // safety check, this should never be hit
            if ((_entityType == null && _complexType == null) ||
                _functionImportMapping == null)
            {
                throw new InvalidOperationException(
                          "InvokeInternal is called when _entityType or _complexType or _functionImportMapping is null.");
            }

            if (_functionImportMapping.ResultMapping == null)
            {
                _functionImportMapping.ResultMapping = new ResultMapping(_functionImportMapping, null);
                XmlModelHelper.NormalizeAndResolve(_functionImportMapping.ResultMapping);
            }

            // first check if we already have one (if found we'll simply return it)
            _createdTypeMapping = _entityType != null
                                      ? _functionImportMapping.ResultMapping.FindTypeMapping(_entityType)
                                      : _functionImportMapping.ResultMapping.FindTypeMapping(_complexType);

            if (_createdTypeMapping == null)
            {
                if (_entityType != null)
                {
                    _createdTypeMapping = new FunctionImportEntityTypeMapping(_functionImportMapping.ResultMapping, null);
                    _createdTypeMapping.TypeName.SetRefName(_entityType);
                }
                else
                {
                    _createdTypeMapping = new FunctionImportComplexTypeMapping(_functionImportMapping.ResultMapping, null);
                    _createdTypeMapping.TypeName.SetRefName(_complexType);
                }

                XmlModelHelper.NormalizeAndResolve(_createdTypeMapping);
                _functionImportMapping.ResultMapping.AddTypeMapping(_createdTypeMapping);
            }

            if (_createDefaultScalarProperties && _createdTypeMapping != null)
            {
                IEnumerable <Property> properties = null;

                if (_entityType != null)
                {
                    properties = _entityType.Properties();
                }
                else if (_complexType != null)
                {
                    properties = _complexType.Properties();
                }

                if (properties != null)
                {
                    foreach (var prop in properties)
                    {
                        // Skip if the property is a Complex Property or if we already have the Scalar Property in the type mapping.
                        if ((prop is ComplexConceptualProperty) == false &&
                            _createdTypeMapping.FindScalarProperty(prop) == null)
                        {
                            var columnName = (_mapPropertyNameToColumnName != null &&
                                              _mapPropertyNameToColumnName.ContainsKey(prop.DisplayName)
                                                  ? _mapPropertyNameToColumnName[prop.DisplayName]
                                                  : prop.DisplayName);
                            CommandProcessor.InvokeSingleCommand(
                                cpc, new CreateFunctionImportScalarPropertyCommand(_createdTypeMapping, prop, columnName));
                        }
                    }
                }
            }
        }
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            // safety check, this should never be hit
            Debug.Assert(
                EntityToBeDerived != null && BaseType != null, "InvokeInternal is called when EntityToBeDerived or BaseType is null");

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

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

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

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

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

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

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

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

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

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

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

            // rebind and verify
            EntityToBeDerived.BaseType.Rebind();
            Debug.Assert(
                EntityToBeDerived.BaseType.Status == BindingStatus.Known,
                "EntityToBeDerived.BaseType.Status should be BindingStatus.Known, instead it is "
                + EntityToBeDerived.BaseType.Status.ToString());
        }
Exemple #17
0
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            var service  = cpc.EditingContext.GetEFArtifactService();
            var artifact = service.Artifact;

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

            // check for uniqueness
            var assocName    = Name;
            var assocSetName = assocName;

            if (UniquifyNames)
            {
                assocName    = ModelHelper.GetUniqueName(typeof(Association), model, assocName);
                assocSetName = ModelHelper.GetUniqueName(typeof(AssociationSet), model.FirstEntityContainer, assocName);
            }
            else
            {
                // check for uniqueness of the association name
                string msg = null;
                if (ModelHelper.IsUniqueName(typeof(Association), model, assocName, false, out msg) == false)
                {
                    throw new InvalidOperationException(msg);
                }

                // check for uniqueness of the association set name
                if (ModelHelper.IsUniqueName(typeof(AssociationSet), model.FirstEntityContainer, assocSetName, false, out msg) == false)
                {
                    throw new InvalidOperationException(msg);
                }
            }

            // create the new item in our model
            var association = new Association(model, null);

            association.LocalName.Value = assocName;
            model.AddAssociation(association);
            XmlModelHelper.NormalizeAndResolve(association);

            // create the ends of the association
            var fkEnd = new AssociationEnd(association, null);

            fkEnd.Type.SetRefName(FkTable);
            fkEnd.Role.Value = FkRoleNameOverride ?? ModelHelper.CreateFKAssociationEndName(FkTable.LocalName.Value);
            if (FkMultiplicityOverride != null)
            {
                fkEnd.Multiplicity.Value = FkMultiplicityOverride;
            }
            else
            {
                fkEnd.Multiplicity.Value = DoesFkFormPk ? ModelConstants.Multiplicity_ZeroOrOne : ModelConstants.Multiplicity_Many;
            }
            association.AddAssociationEnd(fkEnd);
            XmlModelHelper.NormalizeAndResolve(fkEnd);

            var pkEnd = new AssociationEnd(association, null);

            pkEnd.Type.SetRefName(PkTable);
            pkEnd.Role.Value = PkRoleNameOverride ?? ModelHelper.CreatePKAssociationEndName(PkTable.LocalName.Value);
            if (PkMultiplicityOverride != null)
            {
                pkEnd.Multiplicity.Value = PkMultiplicityOverride;
            }
            else
            {
                pkEnd.Multiplicity.Value = IsNullableFk ? ModelConstants.Multiplicity_ZeroOrOne : ModelConstants.Multiplicity_One;
            }
            association.AddAssociationEnd(pkEnd);
            XmlModelHelper.NormalizeAndResolve(pkEnd);

            var cmd = new CreateAssociationSetCommand(assocSetName, association, ModelSpace.Storage);

            CommandProcessor.InvokeSingleCommand(cpc, cmd);
            var set = cmd.AssociationSet;

            Debug.Assert(set != null, "failed to create an AssociationSet");

            Association = association;
            _createdAssociationFkEnd = fkEnd;
            _createdAssociationPkEnd = pkEnd;
        }
Exemple #18
0
 /// <summary>
 ///     This will create a transaction if there isn't one already.  If the CommandProcessorContext is already
 ///     tracking a transaction, then a new one is NOT created.
 /// </summary>
 /// <param name="cpc"></param>
 /// <param name="element">The EFElement to delete</param>
 /// <param name="rebindAllBindings">Control whether all bindings in the artifact should be rebound</param>
 internal static void DeleteInTransaction(CommandProcessorContext cpc, DeleteEFElementCommand cmd, bool rebindAllBindings)
 {
     cmd.RebindAllBindings = rebindAllBindings;
     CommandProcessor.InvokeSingleCommand(cpc, cmd);
 }
        // <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;
            }
        }
        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;
            }
        }
Exemple #21
0
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            Debug.Assert(_entityType != null || _complexType != null, "Undefined parent type");

            if (_entityType != null)
            {
                var propertyName = ModelHelper.GetUniqueConceptualPropertyName(_clipboardProperty.PropertyName, _entityType);

                if (_clipboardProperty.IsComplexProperty)
                {
                    _createdProperty = CreateComplexPropertyCommand.CreateComplexProperty(
                        cpc, propertyName, _entityType, _clipboardProperty.PropertyType,
                        _clipboardProperty.ConcurrencyMode, _clipboardProperty.GetterAccessModifier, _clipboardProperty.SetterAccessModifier,
                        _insertPosition);
                }
                else if (_clipboardProperty.IsConceptualProperty)
                {
                    Debug.Assert(_entityType.EntityModel.IsCSDL, "This should be a c-side Entity");
                    if (_entityType.EntityModel.IsCSDL)
                    {
                        _createdProperty = CreatePropertyCommand.CreateConceptualProperty(
                            cpc, propertyName, _entityType as ConceptualEntityType, _clipboardProperty.PropertyType,
                            _clipboardProperty.IsNullable,
                            _clipboardProperty.Default, _clipboardProperty.ConcurrencyMode, _clipboardProperty.GetterAccessModifier,
                            _clipboardProperty.SetterAccessModifier,
                            _clipboardProperty.MaxLength, _clipboardProperty.FixedLength, _clipboardProperty.Precision,
                            _clipboardProperty.Scale, _clipboardProperty.Unicode, _clipboardProperty.Collation,
                            _clipboardProperty.StoreGeneratedPattern, _insertPosition);
                    }
                }
                else
                {
                    Debug.Assert(_entityType.EntityModel.IsCSDL == false, "This should be a s-side Entity");
                    if (!_entityType.EntityModel.IsCSDL)
                    {
                        _createdProperty = CreatePropertyCommand.CreateStorageProperty(
                            cpc, propertyName, _entityType as StorageEntityType, _clipboardProperty.PropertyType,
                            _clipboardProperty.IsNullable,
                            _clipboardProperty.Default, _clipboardProperty.MaxLength,
                            DefaultableValueBoolOrNone.GetFromNullableBool(_clipboardProperty.FixedLength), _clipboardProperty.Precision,
                            _clipboardProperty.Scale,
                            DefaultableValueBoolOrNone.GetFromNullableBool(_clipboardProperty.Unicode), _clipboardProperty.Collation,
                            _clipboardProperty.ConcurrencyMode);
                    }
                }

                if (_clipboardProperty.IsKeyProperty)
                {
                    var setKey = new SetKeyPropertyCommand(_createdProperty, true);
                    CommandProcessor.InvokeSingleCommand(cpc, setKey);
                }

                AddAnnotations(_clipboardProperty, _createdProperty);
            }
            else
            {
                var cmd = new CopyComplexTypePropertyCommand(_clipboardProperty, _complexType);
                CommandProcessor.InvokeSingleCommand(cpc, cmd);
                _createdProperty = cmd.Property;
            }
        }
        internal override void CreateModelItem(CommandProcessorContext cpc, EditingContext context, EFElement underlyingModelItem)
        {
            Debug.Assert(context != null, "The context argument cannot be null");
            Debug.Assert(StorageEntityType == null, "Don't call this method if we already have a ModelItem");
            Debug.Assert(MappingConceptualEntityType.ConceptualEntityType != null, "The parent item isn't set up correctly");
            Debug.Assert(underlyingModelItem != null, "The underlyingModelItem cannot be null");
            var storeEntityType = underlyingModelItem as EntityType;
            Debug.Assert(
                storeEntityType != null,
                "underlyingModelItem must be of type EntityType, actual type = " + underlyingModelItem.GetType().FullName);
            Debug.Assert(storeEntityType.EntityModel.IsCSDL == false, "The storageEntityType must not be a CSDL EntityType");

            Context = context;
            ColumnMappings.Context = context;

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

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

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

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

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

            try
            {
                // now update the model
                var cp = new CommandProcessor(cpc);
                cp.EnqueueCommand(cmd);
                cp.Invoke();
            }
            catch
            {
                ModelItem = null;
                ColumnMappings.ModelItem = null;
                Parent.RemoveChild(this);
                throw;
            }
        }
        /// <summary>
        ///     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;
        }
        // <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;
            }
        }
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            CreatedAssociation = ModelHelper.FindAssociation(cpc.Artifact.ConceptualModel(), Name);

            if (CreatedAssociation == null)
            {
                // This Association does not exist, create it
                base.InvokeInternal(cpc);
            }
            else
            {
                // The Association already exists, update it
                Debug.Assert(
                    CreatedAssociation.AssociationEnds().Count == 2, "Association element is invalid, it should always have exactly 2 ends");
                if (CreatedAssociation.AssociationEnds().Count == 2)
                {
                    AssociationEnd principal;
                    AssociationEnd dependent;
                    ModelHelper.DeterminePrincipalDependentEndsForAnyAssociationType(CreatedAssociation, out principal, out dependent);

                    if (principal.Type.Target == null ||
                        !string.Equals(principal.Type.Target.Name.Value, End1Entity.LocalName.Value, StringComparison.Ordinal))
                    {
                        principal.Type.SetRefName(End1Entity);
                        principal.Role.Value = End1Entity.LocalName.Value;
                    }

                    if (dependent.Type.Target == null ||
                        !string.Equals(dependent.Type.Target.Name.Value, End2Entity.LocalName.Value, StringComparison.Ordinal))
                    {
                        dependent.Type.SetRefName(End2Entity);
                        var endRoleValue = End2Entity.LocalName.Value;
                        if (principal.Role.Value.Equals(endRoleValue))
                        {
                            // avoid duplicate Role values between the two ends. This will occur in self-associations.
                            // Appending "1" is consistent with how model-gen chooses a unique name.
                            endRoleValue = endRoleValue + "1";
                        }
                        dependent.Role.Value = endRoleValue;
                    }

                    if (!string.Equals(principal.Multiplicity.Value, End1Multiplicity, StringComparison.Ordinal))
                    {
                        principal.Multiplicity.Value = End1Multiplicity;
                    }

                    if (!string.Equals(dependent.Multiplicity.Value, End2Multiplicity, StringComparison.Ordinal))
                    {
                        dependent.Multiplicity.Value = End2Multiplicity;
                    }

                    // We have to resolve the association after both the principal and dependent have been updated here. The reason is because
                    // if we resolve the principal and dependent separately we will end up with duplicate symbols in the symbol table because
                    // the previous end didn't get removed.
                    XmlModelHelper.NormalizeAndResolve(CreatedAssociation);

                    // Also update the AssociationSet
                    var associationSet = CreatedAssociation.AssociationSet;

                    // It's possible for the association to exist but not the associationSet when a rename in the EntityDesigner is propagated
                    // to the database and the resulting hydration events flow back up.
                    if (associationSet == null)
                    {
                        var assocSetName = ModelHelper.GetUniqueName(
                            typeof(AssociationSet), cpc.Artifact.ConceptualModel().FirstEntityContainer, Name);
                        var cmd = new CreateAssociationSetCommand(assocSetName, CreatedAssociation);
                        CommandProcessor.InvokeSingleCommand(cpc, cmd);
                        associationSet = cmd.AssociationSet;
                    }

                    if (associationSet != null &&
                        principal.Type.Status == BindingStatus.Known &&
                        dependent.Type.Status == BindingStatus.Known &&
                        associationSet.PrincipalEnd != null &&
                        associationSet.DependentEnd != null)
                    {
                        associationSet.PrincipalEnd.Role.SetRefName(principal);
                        associationSet.PrincipalEnd.EntitySet.SetRefName(principal.Type.Target.EntitySet);

                        associationSet.DependentEnd.Role.SetRefName(dependent);
                        associationSet.DependentEnd.EntitySet.SetRefName(dependent.Type.Target.EntitySet);
                        XmlModelHelper.NormalizeAndResolve(associationSet);
                    }

                    var navProp1 = principal.GetAntiDependenciesOfType <NavigationProperty>()
                                   .FirstOrDefault(np => np.FromRole.Target == principal);
                    if (navProp1 != null && ShouldCreateNavigationPropertyEnd1)
                    {
                        navProp1.Name.Value = NavigationPropertyInEnd1Entity;
                    }

                    var navProp2 = dependent.GetAntiDependenciesOfType <NavigationProperty>()
                                   .FirstOrDefault(np => np.FromRole.Target == dependent);
                    if (navProp2 != null && ShouldCreateNavigationPropertyEnd2)
                    {
                        navProp2.Name.Value = NavigationPropertyInEnd2Entity;
                    }
                }
            }
        }
        // <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;
            }
        }
        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();
            }
        }
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            if (_diagram != null)
            {
                // Add diagram id information in the transaction context.
                // This is to ensure the diagram objects are created correctly.
                if (cpc.EfiTransaction.GetContextValue <DiagramContextItem>(EfiTransactionOriginator.TransactionOriginatorDiagramId) == null)
                {
                    cpc.EfiTransaction.AddContextValue(
                        EfiTransactionOriginator.TransactionOriginatorDiagramId, new DiagramContextItem(_diagram.Id.Value));
                }
            }

            var service  = cpc.EditingContext.GetEFArtifactService();
            var artifact = service.Artifact;

            // the model that we want to add the entity to
            var model = ModelHelper.GetEntityModel(artifact, _modelSpace);

            var entitiesMap = new Dictionary <EntityTypeClipboardFormat, EntityType>(_clipboardEntities.ClipboardEntities.Count);

            // create copies of EntityTypes
            foreach (var clipboardEntity in _clipboardEntities.ClipboardEntities)
            {
                var cmd = new CopyEntityCommand(_diagram, clipboardEntity, _modelSpace);
                CommandProcessor.InvokeSingleCommand(cpc, cmd);
                entitiesMap.Add(clipboardEntity, cmd.EntityType);
            }

            // create copies of associations
            foreach (var clipboardAssociation in _clipboardEntities.ClipboardAssociations)
            {
                // Check if the association is in the Artifact/model.
                if (_diagram != null)
                {
                    // Get the association by name.
                    var association = artifact.ArtifactSet.LookupSymbol(clipboardAssociation.NormalizedName) as Association;
                    if (association != null)
                    {
                        var entityTypesInAssociation = association.AssociationEnds().Select(ae => ae.Type.Target).ToList();
                        // Check whether the associated entity-types are created in the previous step.
                        // When the user copy and paste an association and the associated entities in the same diagram,
                        // we need to create a new copy of the association in the model. Without the check below, the code will determine that there is no need
                        // to create the copy since the association exist in the model.
                        if (entityTypesInAssociation.Except(entitiesMap.Values).Count() == 0)
                        {
                            // At this point we know that the association that is referred in clipboard exists in the current model.
                            // Next we will check whether this association is represented in diagram or not.
                            // if not, create a new association connector in the diagram.
                            if (association.GetAntiDependenciesOfType <AssociationConnector>()
                                .Count(ac => ac.Diagram.Id == _diagram.Id.Value) == 0)
                            {
                                // AssociationConnector is created by creating EntityTypeShapes that associationEnd refer to.
                                foreach (var associationEnd in association.AssociationEnds())
                                {
                                    var entityType = associationEnd.Type.SafeTarget as ConceptualEntityType;
                                    Debug.Assert(
                                        entityType != null,
                                        "In: CopyEntitiesCommand's  InvokeInternal, associationEnd's Type property should be typeof ConceptualEntityType");
                                    if (entityType != null)
                                    {
                                        // CreateEntityTypeShapeAndConnectorsInDiagram method will check if the shape for the entity-type has been created;
                                        // and it will not create one if the shape already exists in the diagram.
                                        // Also, VerifyDiagramModelIntegrityVisitor will assert if there are duplicate diagram shapes (shapes that point to the same model element)
                                        // every-time a command transaction is committed. So adding another check to do the same thing here is redundant.
                                        CreateEntityTypeShapeCommand.CreateEntityTypeShapeAndConnectorsInDiagram(
                                            cpc, _diagram, entityType, false);
                                    }
                                }
                            }
                            continue;
                        }
                    }
                }
                CopyAssociation(cpc, model, clipboardAssociation, entitiesMap);
            }

            // create copies of inheritances
            foreach (var inheritance in _clipboardEntities.ClipboardInheritances)
            {
                if (_diagram != null)
                {
                    // Check if the underlying entity types are in the artifact/model to do that we need to:
                    // - Get the Entity-Types by name.
                    // - Check whether the entity-types match what were created in copy entities steps.
                    var derivedEntity = artifact.ArtifactSet.LookupSymbol(inheritance.Key.NormalizedName) as EntityType;
                    var baseEntity    = artifact.ArtifactSet.LookupSymbol(inheritance.Value.NormalizedName) as EntityType;
                    if (derivedEntity != null &&
                        baseEntity != null)
                    {
                        if (entitiesMap.Values.Contains(derivedEntity) &&
                            entitiesMap.Values.Contains(baseEntity))
                        {
                            // check if the underlying entity-types are not in the diagram.
                            // InheritanceConnector are created by ensuring both EntityTypeShapes are created.
                            if (derivedEntity.GetAntiDependenciesOfType <EntityTypeShape>().Count(ets => ets.Diagram.Id == _diagram.Id.Value)
                                == 0 &&
                                baseEntity.GetAntiDependenciesOfType <EntityTypeShape>()
                                .Count(ets2 => ets2.Diagram.Id == _diagram.Id.Value) == 0)
                            {
                                // CreateEntityTypeShapeAndConnectorsInDiagram method will check if the shape for the entity-type has been created;
                                // and it will not create one if the shape already exists in the diagram.
                                // Also, VerifyDiagramModelIntegrityVisitor will assert if there are duplicate diagram shapes (shapes that point to the same model element)
                                // every-time a command transaction is committed. So adding another check to do the same thing here is redundant.
                                CreateEntityTypeShapeCommand.CreateEntityTypeShapeAndConnectorsInDiagram(
                                    cpc, _diagram, derivedEntity as ConceptualEntityType, false);
                                CreateEntityTypeShapeCommand.CreateEntityTypeShapeAndConnectorsInDiagram(
                                    cpc, _diagram, baseEntity as ConceptualEntityType, false);
                            }
                            continue;
                        }
                    }
                }
                CopyInheritance(cpc, inheritance, entitiesMap);
            }
        }
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            var service  = cpc.EditingContext.GetEFArtifactService();
            var artifact = service.Artifact;

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

            // check for uniqueness of the association and association set names
            // if uniquifyNames is true then make them unique, otherwise throw
            // an exception if they're not (always uniquify associationSetName
            // regardless as we get bugs if not)
            var assocName    = Name;
            var assocSetName = assocName;

            if (UniquifyNames)
            {
                assocName    = ModelHelper.GetUniqueName(typeof(Association), model, assocName);
                assocSetName = ModelHelper.GetUniqueName(typeof(AssociationSet), model.FirstEntityContainer, assocName);

                // ensure unique NavigationProperty names
                if (ShouldCreateNavigationPropertyEnd1 &&
                    !ModelHelper.IsUniquePropertyName(End1Entity, NavigationPropertyInEnd1Entity, true) ||
                    NavigationPropertyInEnd1Entity == End1Entity.LocalName.Value)
                {
                    var namesToAvoid = new HashSet <string>();
                    namesToAvoid.Add(End1Entity.LocalName.Value);
                    namesToAvoid.Add(NavigationPropertyInEnd2Entity);
                    NavigationPropertyInEnd1Entity = ModelHelper.GetUniqueConceptualPropertyName(
                        NavigationPropertyInEnd1Entity, End1Entity, namesToAvoid);
                }

                if (ShouldCreateNavigationPropertyEnd2 &&
                    !ModelHelper.IsUniquePropertyName(End2Entity, NavigationPropertyInEnd2Entity, true) ||
                    NavigationPropertyInEnd2Entity == End2Entity.LocalName.Value)
                {
                    var namesToAvoid = new HashSet <string> {
                        End2Entity.LocalName.Value, NavigationPropertyInEnd1Entity
                    };
                    NavigationPropertyInEnd2Entity = ModelHelper.GetUniqueConceptualPropertyName(
                        NavigationPropertyInEnd2Entity, End2Entity, namesToAvoid);
                }
            }
            else
            {
                assocSetName = ModelHelper.GetUniqueName(typeof(AssociationSet), model.FirstEntityContainer, assocName);

                string msg = null;
                if (!ModelHelper.IsUniqueName(typeof(Association), model, assocName, false, out msg))
                {
                    throw new InvalidOperationException(msg);
                }
                else if (!ModelHelper.IsUniqueName(typeof(AssociationSet), model.FirstEntityContainer, assocSetName, false, out msg))
                {
                    throw new InvalidOperationException(msg);
                }
                else if (ShouldCreateNavigationPropertyEnd1 &&
                         (!ModelHelper.IsUniquePropertyName(End1Entity, NavigationPropertyInEnd1Entity, true)))
                {
                    msg = string.Format(CultureInfo.CurrentCulture, Resources.NAME_NOT_UNIQUE, NavigationPropertyInEnd1Entity);
                    throw new InvalidOperationException(msg);
                }
                else if (ShouldCreateNavigationPropertyEnd2 &&
                         (!ModelHelper.IsUniquePropertyName(End2Entity, NavigationPropertyInEnd2Entity, true)))
                {
                    msg = string.Format(CultureInfo.CurrentCulture, Resources.NAME_NOT_UNIQUE, NavigationPropertyInEnd2Entity);
                    throw new InvalidOperationException(msg);
                }
                else if (NavigationPropertyInEnd1Entity == End1Entity.LocalName.Value)
                {
                    msg = string.Format(
                        CultureInfo.CurrentCulture, Resources.NavPropNameSameAsContainer, NavigationPropertyInEnd1Entity);
                    throw new InvalidOperationException(msg);
                }
                else if (NavigationPropertyInEnd2Entity == End2Entity.LocalName.Value)
                {
                    msg = string.Format(
                        CultureInfo.CurrentCulture, Resources.NavPropNameSameAsContainer, NavigationPropertyInEnd2Entity);
                    throw new InvalidOperationException(msg);
                }
            }

            // create the new item in our model
            var association = new Association(model, null);

            association.LocalName.Value = assocName;
            model.AddAssociation(association);
            XmlModelHelper.NormalizeAndResolve(association);

            // create the first end
            _end1 = new AssociationEnd(association, null);
            _end1.Type.SetRefName(End1Entity);
            _end1.Role.Value         = End1Entity.LocalName.Value;
            _end1.Multiplicity.Value = End1Multiplicity;
            association.AddAssociationEnd(_end1);
            XmlModelHelper.NormalizeAndResolve(_end1);

            // create the second end
            _end2 = new AssociationEnd(association, null);
            _end2.Type.SetRefName(End2Entity);
            var endRoleValue = End2Entity.LocalName.Value;

            if (_end1.Role.Value.Equals(endRoleValue))
            {
                // avoid duplicate Role values between the two ends. This will occur in self-associations.
                // Appending "1" is consistent with how model-gen chooses a unique name.
                endRoleValue = endRoleValue + "1";
            }
            _end2.Role.Value         = endRoleValue;
            _end2.Multiplicity.Value = End2Multiplicity;
            association.AddAssociationEnd(_end2);
            XmlModelHelper.NormalizeAndResolve(_end2);

            // create the association set for this association
            var cmd = new CreateAssociationSetCommand(assocSetName, association);

            CommandProcessor.InvokeSingleCommand(cpc, cmd);
            var set = cmd.AssociationSet;

            Debug.Assert(set != null, "unable to create association set");

            CreateNavigationPropertyCommand navcmd;

            if (ShouldCreateNavigationPropertyEnd1)
            {
                navcmd = new CreateNavigationPropertyCommand(NavigationPropertyInEnd1Entity, End1Entity, association, _end1, _end2);
                CommandProcessor.InvokeSingleCommand(cpc, navcmd);
            }

            if (ShouldCreateNavigationPropertyEnd2)
            {
                navcmd = new CreateNavigationPropertyCommand(NavigationPropertyInEnd2Entity, End2Entity, association, _end2, _end1);
                CommandProcessor.InvokeSingleCommand(cpc, navcmd);
            }

            if (ShouldCreateForeignKeyProperties)
            {
                CreateForeignKeyProperties.AddRule(cpc, association);
            }

            CreatedAssociation = association;
        }
        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;
            }
        }
Exemple #31
0
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            DesignerInfo designerInfo;

            Debug.Assert(cpc.Artifact != null, "Artifact was null");
            if (Association != null &&
                cpc.Artifact != null &&
                cpc.Artifact.DesignerInfo() != null &&
                cpc.Artifact.DesignerInfo().TryGetDesignerInfo(OptionsDesignerInfo.ElementName, out designerInfo))
            {
                // APPDB_SCENARIO: We cannot use referential constraints for 0..1:0..1 or 1:1 associations, since these exist as configured
                //                 0..1:* or 1:* associations and so introducing a referential constraint would cause validation errors.
                // Must use Referential Constraint for 1:0..1 relationship as using an AssociationSetMapping results in illegal reference to the same ID column twice (since the PK is also the FK)
                if (Association.IsOneToZeroOrOne ||
                    (UseReferentialConstraint && !(Association.IsZeroOrOneToZeroOrOne || Association.IsOneToOne)))
                {
                    // We're including fk columns, so the update will consist of a ref constraint
                    var createRefConCommand = new CreateOrUpdateReferentialConstraintCommand(
                        (c, subCpc) =>
                    {
                        var cmd                 = c as CreateOrUpdateReferentialConstraintCommand;
                        cmd.PrincipalEnd        = PrincipalEnd;
                        cmd.DependentEnd        = DependentEnd;
                        cmd.PrincipalProperties = PrincipalProperties;
                        cmd.DependentProperties = DependentProperties;

                        return(cmd.PrincipalEnd != null && cmd.DependentEnd != null);
                    });

                    CommandProcessor.InvokeSingleCommand(cpc, createRefConCommand);
                }
                else
                {
                    // We're not including fk columns, so the update will consist of an association set mapping and a deletes of the fk columns (if they exist)
                    // otherwise update AssociationSetMapping appropriately
                    var createMapCommand = new CreateOrUpdateAssociationSetMappingCommand(
                        (c, subCpc) =>
                    {
                        var cmd                    = c as CreateOrUpdateAssociationSetMappingCommand;
                        cmd.Association            = Association;
                        cmd.AssociationSet         = AssociationSet;
                        cmd.EntityContainerMapping = EntityContainerMapping;
                        cmd.StorageEntitySet       = StorageEntitySet;

                        return(cmd.Association != null && cmd.AssociationSet != null && cmd.EntityContainerMapping != null &&
                               cmd.StorageEntitySet != null);
                    });

                    CommandProcessor.InvokeSingleCommand(cpc, createMapCommand);

                    // Delete the fk properties in the conceptual layer if they exist. Do not delete primary key properties though!
                    if (!IncludeFkProperties)
                    {
                        var propertiesToDelete =
                            DependentProperties.Where(p => p.EntityType != null && !p.EntityType.ResolvableKeys.Contains(p)).ToList();
                        foreach (var p in propertiesToDelete)
                        {
                            var deletePropertyCmd = new DeletePropertyCommand(
                                (c, subCpc) =>
                            {
                                var cmd       = c as DeletePropertyCommand;
                                cmd.EFElement = p;
                                return(cmd.EFElement != null);
                            });

                            CommandProcessor.InvokeSingleCommand(cpc, deletePropertyCmd);
                        }
                    }

                    // Add or update the EndProperty elements for the AssociationSetMapping. Try to work out which end is the principal
                    // end by looking at the multiplicity, since we don't have a referential constraint in this case.
                    AssociationSetEnd principalSetEnd;
                    AssociationSetEnd dependentSetEnd;

                    Debug.Assert(
                        AssociationSet.AssociationSetEnds().First().Role.Target != null,
                        "Role Target for Association End was null, AssociationSetMapping update failed");
                    if (AssociationSet.AssociationSetEnds().First().Role.Target != null)
                    {
                        if (Association.End1.Multiplicity.Value == ModelConstants.Multiplicity_Many)
                        {
                            principalSetEnd = AssociationSet.AssociationSetEnds().Last();
                            dependentSetEnd = AssociationSet.AssociationSetEnds().First();
                        }
                        else
                        {
                            principalSetEnd = AssociationSet.AssociationSetEnds().First();
                            dependentSetEnd = AssociationSet.AssociationSetEnds().Last();
                        }

                        var dependentEndPropertyCmd = new CreateOrUpdateEndPropertyCommand(
                            (c, subCpc) =>
                        {
                            var cmd = c as CreateOrUpdateEndPropertyCommand;
                            cmd.AssociationSetEnd       = dependentSetEnd;
                            cmd.AssociationSetMapping   = createMapCommand.AssociationSetMapping;
                            cmd.StorageKeyProperties    = StorageDependentTypeKeyProperties;
                            cmd.ConceptualKeyProperties =
                                ConceptualDependentType.SafeInheritedAndDeclaredProperties.Where(p => p.IsKeyProperty);

                            return(cmd.AssociationSetEnd != null && cmd.AssociationSetMapping != null);
                        });

                        var principalEndPropertyCmd = new CreateOrUpdateEndPropertyCommand(
                            (c, subCpc) =>
                        {
                            var cmd = c as CreateOrUpdateEndPropertyCommand;
                            cmd.AssociationSetEnd       = principalSetEnd;
                            cmd.AssociationSetMapping   = createMapCommand.AssociationSetMapping;
                            cmd.StorageKeyProperties    = StorageDependentTypeForeignKeyProperties;
                            cmd.ConceptualKeyProperties =
                                ConceptualPrincipalType.SafeInheritedAndDeclaredProperties.Where(p => p.IsKeyProperty);

                            return(cmd.AssociationSetEnd != null && cmd.AssociationSetMapping != null);
                        });

                        CommandProcessor.InvokeSingleCommand(cpc, dependentEndPropertyCmd);
                        CommandProcessor.InvokeSingleCommand(cpc, principalEndPropertyCmd);
                    }
                }
            }
        }
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            // safety check, this should never be hit
            Debug.Assert(_derivedType != null, "InvokeInternal is called when DerivedType is null.");
            if (_derivedType == null)
            {
                throw new InvalidOperationException("InvokeInternal is called when DerivedType is null.");
            }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            //
            //  if there are any referential constraints properties whose principal ends refer to keys in the
            //  old derived type, delete them
            //
            foreach (var end in _derivedType.GetAntiDependenciesOfType <AssociationEnd>())
            {
                foreach (var role in end.GetAntiDependenciesOfType <ReferentialConstraintRole>())
                {
                    var rc = role.Parent as ReferentialConstraint;
                    if (rc != null &&
                        rc.Principal == role)
                    {
                        foreach (var pr in rc.Principal.PropertyRefs)
                        {
                            Command cmd = new DeleteReferentialConstraintPropertyRefCommand(pr);
                            // don't invoke this command now, as it will modify the collection we're iterating over
                            CommandProcessor.EnqueueCommand(cmd);
                        }
                    }
                }
            }
        }
        /// <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 #34
0
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            Debug.Assert(Model != null, "Model was null, could not refresh PKs");
            if (Model != null)
            {
                foreach (var entityType in Model.EntityTypes())
                {
                    var storageEntityType    = entityType as StorageEntityType;
                    var conceptualEntityType = entityType as ConceptualEntityType;

                    SchemaQualifiedName entityNameToLookFor = null;
                    if (storageEntityType != null)
                    {
                        var entitySet = storageEntityType.EntitySet as StorageEntitySet;
                        entityNameToLookFor = new SchemaQualifiedName(entitySet.Schema.Value, entitySet.Table.Value);
                    }
                    else if (conceptualEntityType != null)
                    {
                        // If this EntityType has a base type, it should not have any keys.
                        if (conceptualEntityType.BaseType.Target != null)
                        {
                            continue;
                        }
                        entityNameToLookFor = new SchemaQualifiedName(entityType.Name.Value);
                    }

                    Debug.Assert(
                        entityNameToLookFor != null, "Should have created an entity name to look for based off of the current EntityType");
                    if (entityNameToLookFor != null)
                    {
                        var entityNameToRefresh = EntityTypePks.Keys.FirstOrDefault(name => name.Equals(entityNameToLookFor));
                        if (entityNameToRefresh != null)
                        {
                            // Update primary key properties that have changed
                            foreach (var prop in entityType.Properties())
                            {
                                SetKeyPropertyCommand cmd = null;

                                if (prop.IsKeyProperty &&
                                    EntityTypePks[entityNameToRefresh].All(
                                        c => string.Compare(c, prop.Name.Value, StringComparison.Ordinal) != 0))
                                {
                                    // This primary key was removed
                                    cmd = new SetKeyPropertyCommand(prop, false);
                                }
                                else if (prop.IsKeyProperty == false &&
                                         EntityTypePks[entityNameToRefresh].Any(
                                             c => string.Compare(c, prop.Name.Value, StringComparison.Ordinal) == 0))
                                {
                                    // This primary key was added
                                    cmd = new SetKeyPropertyCommand(prop, true);
                                }

                                if (cmd != null)
                                {
                                    CommandProcessor.InvokeSingleCommand(cpc, cmd);
                                }
                            }
                        }
                        else
                        {
                            // If we couldn't find the entity type in the dictionary, then it has no keys. Remove any existing ones.
                            foreach (var keyProp in entityType.ResolvableKeys)
                            {
                                CommandProcessor.InvokeSingleCommand(cpc, new SetKeyPropertyCommand(keyProp, false));
                            }
                        }
                    }
                }
            }
        }
Exemple #35
0
        internal static void CreateEntityTypeShapeAndConnectorsInDiagram(
            CommandProcessorContext cpc, Diagram diagram, ConceptualEntityType entity, Color entityTypeShapeFillColor,
            bool createRelatedEntityTypeShapes)
        {
            // if the entity type shape has been created, return immediately.
            if (entity == null ||
                entity.GetAntiDependenciesOfType <EntityTypeShape>().Count(ets => ets.Diagram.Id == diagram.Id.Value) > 0)
            {
                return;
            }

            var createEntityTypeShapecommand = new CreateEntityTypeShapeCommand(diagram, entity, entityTypeShapeFillColor);

            createEntityTypeShapecommand.PostInvokeEvent += (o, eventsArgs) =>
            {
                if (createEntityTypeShapecommand.EntityTypeShape != null)
                {
                    var relatedEntityTypesNotInDiagram = new List <EntityType>();

                    var entityTypesInDiagram = new HashSet <EntityType>(diagram.EntityTypeShapes.Select(ets => ets.EntityType.Target));

                    // add inheritance connector if the base type exists in the diagram.
                    if (entity.SafeBaseType != null)
                    {
                        if (entityTypesInDiagram.Contains(entity.SafeBaseType))
                        {
                            CommandProcessor.InvokeSingleCommand(cpc, new CreateInheritanceConnectorCommand(diagram, entity));
                        }
                        else
                        {
                            relatedEntityTypesNotInDiagram.Add(entity.SafeBaseType);
                        }
                    }

                    // add the inheritance connector if the derived type exist in the diagram.
                    foreach (var derivedEntityType in entity.ResolvableDirectDerivedTypes)
                    {
                        if (entityTypesInDiagram.Contains(derivedEntityType))
                        {
                            CommandProcessor.InvokeSingleCommand(cpc, new CreateInheritanceConnectorCommand(diagram, derivedEntityType));
                        }
                        else
                        {
                            relatedEntityTypesNotInDiagram.Add(derivedEntityType);
                        }
                    }

                    // Find all associations which the entity type participates.
                    var participatingAssociations = Association.GetAssociationsForEntityType(entity);

                    foreach (var association in participatingAssociations)
                    {
                        var entityTypesInAssociation = association.AssociationEnds().Select(ae => ae.Type.Target).ToList();
                        var entityTypesNotInDiagram  = entityTypesInAssociation.Except(entityTypesInDiagram).ToList();

                        if (entityTypesNotInDiagram.Count == 0)
                        {
                            CommandProcessor.InvokeSingleCommand(cpc, new CreateAssociationConnectorCommand(diagram, association));
                        }
                        relatedEntityTypesNotInDiagram.AddRange(entityTypesNotInDiagram);
                    }

                    if (createRelatedEntityTypeShapes)
                    {
                        foreach (var entityType in relatedEntityTypesNotInDiagram)
                        {
                            // we only want to bring entity-type directly related to the entity-type, so set createRelatedEntityTypeShapes flag to false.
                            CreateEntityTypeShapeAndConnectorsInDiagram(
                                cpc, diagram, entityType as ConceptualEntityType, entityTypeShapeFillColor, false);
                        }
                    }
                }
            };
            CommandProcessor.InvokeSingleCommand(cpc, createEntityTypeShapecommand);
        }
        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;
            }
        }
        /// <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;
        }
        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);
                }
            }
        }
        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;
        }
        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();
            }
        }
Exemple #41
0
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            var service  = cpc.EditingContext.GetEFArtifactService();
            var artifact = service.Artifact;

            Debug.Assert(artifact != null, "Null Artifact");
            if (null == artifact)
            {
                return;
            }

            // construct a mapping of the existing model's C-side objects
            // and their S-side identities before anything is updated
            var existingModel = new ExistingModelSummary(artifact);

            // replace the old SSDL with the new and fixup any references
            // in the MSL that broke because of the replacement of the SSDL
            // (i.e. the S-side Alias and S-side EntityContainer name)
            var replaceSsdlCommand = new ReplaceSsdlCommand(_newArtifactFromDB.StorageModel());

            CommandProcessor.InvokeSingleCommand(cpc, replaceSsdlCommand);

            // remove any mappings with references which no longer work
            // with the new SSDL
            var deleteUnboundMappingsCommand = new DeleteUnboundMappingsCommand();

            CommandProcessor.InvokeSingleCommand(cpc, deleteUnboundMappingsCommand);

            // remove any mappings which should no longer be mapped with the new SSDL
            // but actually are because a new S-side object with identical name
            // but different identity has been added
            var deleteChangedIdentityMappingsCommand = new DeleteChangedIdentityMappingsCommand(existingModel);

            CommandProcessor.InvokeSingleCommand(cpc, deleteChangedIdentityMappingsCommand);

            // from the temp model for the updated database determine which
            // C-side objects need to be added/updated and then update the
            // C- and M- side models appropriately
            var modelFromUpdatedDatabase = new UpdatedModelSummary(_newArtifactFromDB);
            var updateCsdlAndMslCommand  =
                new UpdateConceptualAndMappingModelsCommand(existingModel, modelFromUpdatedDatabase);

            CommandProcessor.InvokeSingleCommand(cpc, updateCsdlAndMslCommand);

            // fix up Function Import parameters and add integrity checks
            if (artifact.MappingModel() != null &&
                artifact.MappingModel().FirstEntityContainerMapping != null)
            {
                // Function Import parameters are now out-of-date compared to the updated Function ones.
                // We need to update them as otherwise there is no way to do so using Escher.
                foreach (var fim in artifact.MappingModel().FirstEntityContainerMapping.FunctionImportMappings())
                {
                    if (null != fim.FunctionImportName &&
                        null != fim.FunctionImportName.Target &&
                        null != fim.FunctionName &&
                        null != fim.FunctionName.Target)
                    {
                        CreateFunctionImportCommand.UpdateFunctionImportParameters(
                            cpc, fim.FunctionImportName.Target, fim.FunctionName.Target);
                    }
                }

                // Add integrity checks to enforce mapping rules
                foreach (var esm in artifact.MappingModel().FirstEntityContainerMapping.EntitySetMappings())
                {
                    EnforceEntitySetMappingRules.AddRule(cpc, esm);
                }

                // add the integrity check to propagate all appropriate StoreGeneratedPattern values to the S-side
                // Note: should not propagate "None"/defaulted values to prevent those C-side values overwriting
                // correctly updated S-side StoreGeneratedPattern values which were just received from the runtime
                PropagateStoreGeneratedPatternToStorageModel.AddRule(cpc, artifact, false);

                // Add integrity check to enforce synchronizing C-side Property facets to S-side values
                var shouldSynchronizePropertyFacets = ModelHelper.GetDesignerPropertyValueFromArtifactAsBool(
                    OptionsDesignerInfo.ElementName,
                    OptionsDesignerInfo.AttributeSynchronizePropertyFacets, OptionsDesignerInfo.SynchronizePropertyFacetsDefault(artifact),
                    artifact);
                if (shouldSynchronizePropertyFacets)
                {
                    PropagateStoragePropertyFacetsToConceptualModel.AddRule(cpc, artifact);
                }
            }
        }
Exemple #42
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;
            }
        }
Exemple #43
0
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            // get unique name for the property
            var propertyName = ModelHelper.GetUniqueName(typeof(ConceptualProperty), _parentComplexType, _clipboardProperty.PropertyName);

            if (!_clipboardProperty.IsComplexProperty)
            {
                // scalar property case
                var cmd = new CreateComplexTypePropertyCommand(
                    propertyName, _parentComplexType, _clipboardProperty.PropertyType, _clipboardProperty.IsNullable);
                CommandProcessor.InvokeSingleCommand(cpc, cmd);
                _createdProperty = cmd.Property;
            }
            else
            {
                // complex property case
                // first try to find ComplexType by it's name
                var complexTypeNormalizedName = EFNormalizableItemDefaults.DefaultNameNormalizerForEDM(
                    _parentComplexType, _clipboardProperty.PropertyType);
                var         items       = _parentComplexType.Artifact.ArtifactSet.GetSymbolList(complexTypeNormalizedName.Symbol);
                ComplexType complexType = null;
                foreach (var efElement in items)
                {
                    // the GetSymbolList() method might return more than one element so choose the first ComplexType
                    complexType = efElement as ComplexType;
                    if (complexType != null)
                    {
                        break;
                    }
                }
                if (complexType != null)
                {
                    // if the ComplexType is found, simply use the create command
                    var cmd = new CreateComplexTypePropertyCommand(propertyName, _parentComplexType, complexType, false);
                    CommandProcessor.InvokeSingleCommand(cpc, cmd);
                    _createdProperty = cmd.Property;
                }
                else
                {
                    // in this case we're going to create ComplexProperty with unresolved type
                    var complexProperty = new ComplexConceptualProperty(_parentComplexType, null);
                    complexProperty.ComplexType.SetXAttributeValue(_clipboardProperty.PropertyType);
                    // set the name and add to the parent entity
                    complexProperty.LocalName.Value = propertyName;
                    _parentComplexType.AddProperty(complexProperty);

                    // set other attributes of the property
                    complexProperty.Nullable.Value = BoolOrNone.FalseValue;

                    XmlModelHelper.NormalizeAndResolve(complexProperty);
                    Debug.Assert(
                        complexProperty.ComplexType.Status != BindingStatus.Known,
                        "Why didn't we find the ComplexType in the ArtifactSet previously?");
                    _createdProperty = complexProperty;
                }
            }

            // safety check
            Debug.Assert(_createdProperty != null, "We didn't get good Property out of the command");
            if (_createdProperty != null)
            {
                // set Property attributes
                var cmd2 = new SetConceptualPropertyFacetsCommand(
                    _createdProperty, _clipboardProperty.Default,
                    _clipboardProperty.ConcurrencyMode, _clipboardProperty.GetterAccessModifier, _clipboardProperty.SetterAccessModifier,
                    _clipboardProperty.MaxLength,
                    DefaultableValueBoolOrNone.GetFromNullableBool(_clipboardProperty.FixedLength), _clipboardProperty.Precision,
                    _clipboardProperty.Scale,
                    DefaultableValueBoolOrNone.GetFromNullableBool(_clipboardProperty.Unicode), _clipboardProperty.Collation);
                CommandProcessor.InvokeSingleCommand(cpc, cmd2);
            }
        }
        /// <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;
        }
        public void RunFinished()
        {
            if (_edmxItem == null)
            {
                if (_modelBuilderSettings.GenerationOption == ModelGenerationOption.EmptyModelCodeFirst
                    || _modelBuilderSettings.GenerationOption == ModelGenerationOption.CodeFirstFromDatabase)
                {
                    Debug.Assert(
                        _modelBuilderSettings.ModelBuilderEngine == null ^
                        _modelBuilderSettings.GenerationOption == ModelGenerationOption.CodeFirstFromDatabase,
                        "Model should be null for Empty Model and not null CodeFirst from database");

                    AddCodeFirstItems();
                }

                return;
            }

            var fileExtension = Path.GetExtension(_edmxItem.FileNames[1]);

            Debug.Assert(
                _modelBuilderSettings.Project.Equals(_edmxItem.ContainingProject),
                "ActiveSolutionProject is not the EDMX file's containing project");
            using (new VsUtils.HourglassHelper())
            {
                var package = PackageManager.Package;
                Window window = null;

                try
                {
                    ConfigFileHelper.UpdateConfig(_modelBuilderSettings);

                    // save the model generated in the wizard UI.
                    if (_modelBuilderSettings.GenerationOption == ModelGenerationOption.GenerateFromDatabase)
                    {
                        var writingModelWatch = new Stopwatch();
                        writingModelWatch.Start();
                        var modelEdmx = ((EdmxModelBuilderEngine)_modelBuilderSettings.ModelBuilderEngine).Edmx;

                        if (!string.Equals(fileExtension, EntityDesignArtifact.ExtensionEdmx, StringComparison.OrdinalIgnoreCase))
                        {
                            // convert the file if this isn't EDMX
                            var edmxFileInfo = new FileInfo(_edmxItem.FileNames[1]);
                            var conversionContext = new ModelConversionContextImpl(
                                _edmxItem.ContainingProject,
                                _edmxItem,
                                edmxFileInfo,
                                _modelBuilderSettings.TargetSchemaVersion,
                                modelEdmx);
                            VSArtifact.DispatchToConversionExtensions(
                                EscherExtensionPointManager.LoadModelConversionExtensions(),
                                fileExtension,
                                conversionContext,
                                loading: false);
                            File.WriteAllText(edmxFileInfo.FullName, conversionContext.OriginalDocument);
                        }
                        else
                        {
                            // we need to use XmlWriter to output so that XmlDeclaration is preserved.
                            using (var modelWriter = XmlWriter.Create(
                                _edmxItem.FileNames[1],
                                new XmlWriterSettings { Indent = true }))
                            {
                                modelEdmx.WriteTo(modelWriter);
                            }
                        }

                        writingModelWatch.Stop();
                        VsUtils.LogOutputWindowPaneMessage(
                            _edmxItem.ContainingProject,
                            string.Format(
                                CultureInfo.CurrentCulture,
                                Properties.Resources.WritingModelTimeMsg,
                                writingModelWatch.Elapsed));
                    }

                    // set the ItemType for the generated .edmx file
                    if (_modelBuilderSettings.VSApplicationType != VisualStudioProjectSystem.Website
                        && string.Equals(
                            fileExtension,
                            EntityDesignArtifact.ExtensionEdmx,
                            StringComparison.OrdinalIgnoreCase))
                    {
                        _edmxItem.Properties.Item(ItemTypePropertyName).Value = EntityDeployBuildActionName;
                    }

                    // now open created file in VS using default viewer
                    window = _edmxItem.Open(Constants.vsViewKindPrimary);
                    Debug.Assert(window != null, "Unable to get window for created edmx file");

                }
                finally
                {
                    package.ModelGenErrorCache.RemoveErrors(_edmxItem.FileNames[1]);
                }

                // Construct an editing context and make all final edits that require the file is opened.
                var edmxFileUri = new Uri(_edmxItem.FileNames[1]);
                var designArtifact =
                    package.ModelManager.GetNewOrExistingArtifact(
                        edmxFileUri, new VSXmlModelProvider(package, package)) as EntityDesignArtifact;
                Debug.Assert(
                    designArtifact != null,
                    "artifact should be of type EntityDesignArtifact but received type " + designArtifact.GetType().FullName);
                Debug.Assert(
                    designArtifact.StorageModel != null, "designArtifact StorageModel cannot be null for Uri " + edmxFileUri.AbsolutePath);
                Debug.Assert(
                    designArtifact.ConceptualModel != null,
                    "designArtifact ConceptualModel cannot be null for Uri " + edmxFileUri.AbsolutePath);

                if (designArtifact != null
                    && designArtifact.StorageModel != null
                    && designArtifact.ConceptualModel != null)
                {
                    var designerSafeBeforeAddingTemplates = designArtifact.IsDesignerSafe;

                    var editingContext =
                        package.DocumentFrameMgr.EditingContextManager.GetNewOrExistingContext(designArtifact.Uri);
                    Debug.Assert(editingContext != null, "Null EditingContext for artifact " + edmxFileUri.AbsolutePath);
                    if (editingContext != null)
                    {
                        // Add DbContext templates when generation is GenerateFromDatabase. (connection is configured)
                        if (_modelBuilderSettings.GenerationOption == ModelGenerationOption.GenerateFromDatabase)
                        {
                            new DbContextCodeGenerator().AddDbContextTemplates(
                                _edmxItem,
                                _modelBuilderSettings.UseLegacyProvider);
                        }

                        // Create FunctionImports for every new Function
                        var cp = PrepareCommandsAndIntegrityChecks(_modelBuilderSettings, editingContext, designArtifact);

                        if (DbContextCodeGenerator.TemplateSupported(_edmxItem.ContainingProject, package))
                        {
                            // Add command setting CodeGenerationStrategy to "None" for EmptyModel. (connection is not yet configured)
                            // NOTE: For EmptyModel, the templates will be added after the connection is configured.
                            //       (i.e. during "Generate Database from Model" or "Refresh from Database")
                            if (_modelBuilderSettings.GenerationOption == ModelGenerationOption.EmptyModel)
                            {
                                var cmd = EdmUtils.SetCodeGenStrategyToNoneCommand(designArtifact);
                                if (cmd != null)
                                {
                                    if (cp == null)
                                    {
                                        var cpc = new CommandProcessorContext(
                                            editingContext,
                                            EfiTransactionOriginator.CreateNewModelId,
                                            Resources.Tx_SetCodeGenerationStrategy);
                                        cp = new CommandProcessor(cpc, cmd);
                                    }
                                    else
                                    {
                                        cp.EnqueueCommand(cmd);
                                    }
                                }
                            }
                        }
                        else
                        {
                            // Templates not supported, add reference to SDE. (.NET Framework 3.5)
                            VsUtils.AddProjectReference(_edmxItem.ContainingProject, "System.Data.Entity");
                        }

                        if (cp != null)
                        {
                            cp.Invoke();
                        }

                        // save the artifact to make it look as though updates were part of creation
                        _edmxItem.Save();

                        if (_modelBuilderSettings.GenerationOption == ModelGenerationOption.GenerateFromDatabase
                            && !designerSafeBeforeAddingTemplates)
                        {
                            // If the artifact became safe after adding references we need to reload it (this can happen 
                            // on .NET Framework 4 where we would originally create a v3 edmx if the user selected EF6 - 
                            // the artifact will be flagged as invalid since there is no runtime which could handle v3 
                            // but after we added references to EF6 the artifacts becomes valid and need to be reloaded). 
                            designArtifact.DetermineIfArtifactIsDesignerSafe();
                            if (designArtifact.IsDesignerSafe)
                            {
                                Debug.Assert(!designArtifact.IsDirty, "Reloading dirty artifact - changes will be lost.");

                                // Since the artifact was originally not valid we did not create the diagram for it. 
                                // Using ReloadDocData will cause the diagram to be recreated. Note we don't need to 
                                // reload the artifact itself since it has not changed.
                                ((DocData)
                                 VSHelpers.GetDocData(package, designArtifact.Uri.LocalPath)).ReloadDocData(0);
                            }
                        }
                    }

                    if (window != null)
                    {
                        window.Activate();
                    }
                }
            }
        }
        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"));
                                });
                    });
        }
        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);
                                });
                    });
        }
        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 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();
        }
Exemple #51
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;
                }
            }
        }