protected override void InvokeInternal(CommandProcessorContext cpc) { var associationSetMapping = ModelHelper.FindAssociationSetMappingForConceptualAssociation(Association); if (associationSetMapping == null) { // This AssociationSetMapping does not exist, create it base.InvokeInternal(cpc); associationSetMapping = AssociationSetMapping; Debug.Assert(associationSetMapping != null, "Could not create AssociationSetMapping"); } else { // The AssociationSetMapping already exists, update it associationSetMapping.Name.SetRefName(AssociationSet); associationSetMapping.TypeName.SetRefName(Association); associationSetMapping.StoreEntitySet.SetRefName(StorageEntitySet); XmlModelHelper.NormalizeAndResolve(associationSetMapping); Debug.Assert(associationSetMapping.Name.Target != null, "Could not resolve association set reference"); Debug.Assert(associationSetMapping.TypeName.Target != null, "Could not resolve association type reference"); Debug.Assert(associationSetMapping.StoreEntitySet.Target != null, "Could not resolve table reference"); InferReferentialConstraints.AddRule(cpc, Association); } }
protected override void InvokeInternal(CommandProcessorContext cpc) { // safety check, this should never be hit Debug.Assert(_binding != null, "InvokeInternal is called when _binding is null."); if (_binding == null) { throw new InvalidOperationException("InvokeInternal is called when _binding is null"); } // set new values in if we were sent them if (_entityProperty != null && _binding.Name.Target != _entityProperty) { _binding.Name.SetRefName(_entityProperty); } // set new values in if we were sent them if (_columnName != null && !string.Equals(_binding.ColumnName.Value, _columnName, StringComparison.CurrentCulture)) { _binding.ColumnName.Value = _columnName; } XmlModelHelper.NormalizeAndResolve(_binding); }
protected override void InvokeInternal(CommandProcessorContext cpc) { if (_enumType.IsFlags.Value != _isFlag) { _enumType.IsFlags.Value = _isFlag; } }
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) { if (context == null || context.Instance == null) { return value; } var desc = context.Instance as EFAssociationDescriptor; if (desc != null) { var assoc = desc.WrappedItem as Association; if (assoc != null) { var commands = ReferentialConstraintDialog.LaunchReferentialConstraintDialog(assoc); var cpc = new CommandProcessorContext( desc.EditingContext, EfiTransactionOriginator.PropertyWindowOriginatorId, Resources.Tx_ReferentialContraint); var cp = new CommandProcessor(cpc); foreach (var c in commands) { cp.EnqueueCommand(c); } cp.Invoke(); } } return value; }
protected override void InvokeInternal(CommandProcessorContext cpc) { Debug.Assert(_property != null, "Property is null"); if (_property == null) { throw new InvalidOperationException("InvokeInternal is called when _property is null."); } if (_property.ComplexType.Target == _newType) { // no change needed return; } // check for ComplexType circular definition var parent = _property.Parent as ComplexType; if (parent != null) { if (ModelHelper.ContainsCircularComplexTypeDefinition(parent, _newType)) { throw new CommandValidationFailedException( String.Format( CultureInfo.CurrentCulture, Resources.Error_CircularComplexTypeDefinitionOnChange, _newType.LocalName.Value)); } } // Update to new type _property.ComplexType.SetRefName(_newType); _property.ComplexType.Rebind(); Debug.Assert(_property.ComplexType.Status == BindingStatus.Known, "Rebind for the ComplexType failed"); }
protected override void PreInvoke(CommandProcessorContext cpc) { // Save off the deleted function mport name DeletedFunctionImportName = FunctionImport.Name.Value; base.PreInvoke(cpc); }
protected override void PreInvoke(CommandProcessorContext cpc) { // save off the deleted entity type name SaveDeletedInformation(); EnforceEntitySetMappingRules.AddRule(cpc, EntityTypeMapping.EntitySetMapping); base.PreInvoke(cpc); }
internal override void Invoke(CommandProcessorContext cpc) { var viewModel = _inheritance.GetRootViewModel(); Debug.Assert(viewModel != null, "Unable to find root view model from inheritance: " + _inheritance); if (viewModel != null) { if (ViewUtils.SetBaseEntityType(cpc, _derivedEntity, _baseEntity)) { viewModel.ModelXRef.Add(_derivedEntity.BaseType, _inheritance, viewModel.EditingContext); } else { try { // setting null will clear out the selection, which may be this Inheritance thing we are deleting viewModel.GetDiagram().ActiveDiagramView.Selection.Set((DiagramItem)null); // in this case inheritance was not created in the model, so we need to delete it from the view model // we don't want any rules to fire for this, so suspend them temporarly _inheritance.Store.RuleManager.SuspendRuleNotification(); using (var t = _inheritance.Store.TransactionManager.BeginTransaction()) { _inheritance.Delete(); t.Commit(); } } finally { _inheritance.Store.RuleManager.ResumeRuleNotification(); } } } }
protected override void InvokeInternal(CommandProcessorContext cpc) { if (_entityProperty != null) { Debug.Assert(_entityProperty.EntityModel.IsCSDL, "_entityProperty should be from C-side model"); ScalarProperty.Name.SetRefName(_entityProperty); } if (TableColumn != null) { Debug.Assert(TableColumn.EntityModel.IsCSDL != true, "_tableColumn should not be from C-side model"); ScalarProperty.ColumnName.SetRefName(TableColumn); } XmlModelHelper.NormalizeAndResolve(ScalarProperty); // if we change a scalar in an association mapping, make sure that we still have good MSL if (ScalarProperty.EndProperty != null) { var asm = ScalarProperty.EndProperty.Parent as AssociationSetMapping; Debug.Assert(asm != null, "_sp.EndProperty parent is not an AssociationSetMapping"); if (asm != null) { EnforceAssociationSetMappingRules.AddRule(cpc, asm); var assoc = asm.TypeName.Target; Debug.Assert(assoc != null, "Could not resolve association reference"); if (assoc != null) { InferReferentialConstraints.AddRule(cpc, assoc); } } } }
protected override void InvokeInternal(CommandProcessorContext cpc) { try { // check that we have an existing artifact var service = cpc.EditingContext.GetEFArtifactService(); var existingArtifact = service.Artifact as EntityDesignArtifact; Debug.Assert(existingArtifact != null, "Null Artifact in ReplaceCsdlAndMslCommand.InvokeInternal()"); if (null == existingArtifact) { return; } // replace the old CSDL with the new ReplaceCsdl(cpc, existingArtifact, _newCsdlReader); // replace the old MSL with the new ReplaceMsl(cpc, existingArtifact, _newMslReader); // normalize and resolve the ConceptualModel XmlModelHelper.NormalizeAndResolve(existingArtifact.ConceptualModel); Debug.Assert(EFElementState.Resolved == existingArtifact.ConceptualModel.State, "ConceptualModel State should be Resolved"); // normalize and resolve the MappingModel XmlModelHelper.NormalizeAndResolve(existingArtifact.MappingModel); Debug.Assert(EFElementState.Resolved == existingArtifact.MappingModel.State, "MappingModel State should be Resolved"); } finally { Cleanup(); } }
protected override void InvokeInternal(CommandProcessorContext cpc) { Debug.Assert(_properties != null && _properties.Count > 0, "There is no property to be moved."); if (_properties != null && _properties.Count > 0) { Debug.Assert(_step > 0, "Parameter step value is not valid. The value must be greater than 0."); if (_step > 0) { // Properties are moved in the following order: // - If the properties are moved forward (MoveDirection == Down), we need to move the property that are closer to the last-property first. // - If the properties are moved backward (MoveDirection == Up), we need to move the property that are closer to the first-property first. var sortedProperties = ModelHelper.GetListOfPropertiesInTheirXElementsOrder(_properties); Debug.Assert( sortedProperties.Count == _properties.Count, "The sorted properties should have the same number of properties."); PropertyBase previouslyMovedProperty = null; foreach (var property in (_moveDirection == MoveDirection.Up ? sortedProperties : sortedProperties.Reverse())) { // Ensure that properties are moved don't change order. // For example: if property A, B and C are moved forward, the move should not cause property A to be placed after Property B. var numberOfSteps = GetNumberOfMoveStep(property, previouslyMovedProperty); if (numberOfSteps > 0) { CommandProcessor.InvokeSingleCommand(cpc, new MovePropertyCommand(property, _moveDirection, numberOfSteps)); } previouslyMovedProperty = property; } } } }
protected override void InvokeInternal(CommandProcessorContext cpc) { var fae = FunctionScalarProperty.AssociationEnd; var fcp = FunctionScalarProperty.FunctionComplexProperty; if (fae != null && fae.ScalarProperties().Count == 1) { // we are the last one, so remove the entire AssociationEnd DeleteInTransaction(cpc, FunctionScalarProperty.AssociationEnd); } else if (fcp != null && fcp.ScalarProperties().Count == 1 && fcp.ComplexProperties().Count == 0) { // we are about to remove the last item from this FunctionComplexProperty, so remove the entire FunctionComplexProperty Debug.Assert( fcp.ScalarProperties()[0] == FunctionScalarProperty, "fcp.ScalarProperties()[0] should be the same as this.FunctionScalarProperty"); DeleteInTransaction(cpc, fcp); } else { // all other cases, just remove the ScalarProperty base.InvokeInternal(cpc); } }
internal static void StaticInvoke(CommandProcessorContext cpc, InheritanceConnector inheritanceConnector) { // if there was a circular inheritance, this connector will be deleted, if so, we just return if (inheritanceConnector.IsDeleted) { return; } var viewModel = inheritanceConnector.GetRootViewModel(); Debug.Assert( viewModel != null, "Unable to find root view model from inheritance connector: " + inheritanceConnector.AccessibleName); if (viewModel != null) { var modelEntityTypeBase = viewModel.ModelXRef.GetExisting(inheritanceConnector.ModelElement) as EntityTypeBaseType; if (modelEntityTypeBase != null) { var modelEntity = modelEntityTypeBase.Parent as EntityType; var modelDiagram = viewModel.ModelXRef.GetExisting(inheritanceConnector.Diagram) as Diagram; Debug.Assert(modelEntity != null && modelDiagram != null); if (modelEntity != null && modelDiagram != null) { var cmd = new CreateInheritanceConnectorCommand(modelDiagram, modelEntity); CommandProcessor.InvokeSingleCommand(cpc, cmd); var modelInheritanceConnector = cmd.InheritanceConnector; viewModel.ModelXRef.Add(modelInheritanceConnector, inheritanceConnector, viewModel.EditingContext); } } } }
protected override void InvokeInternal(CommandProcessorContext cpc) { Debug.Assert(cpc != null, "InvokeInternal is called when EntityContainerMapping is null."); // safety check, this should never be hit if (EntityType == null) { throw new InvalidOperationException("InvokeInternal is called when entity type is null"); } EntityType.Abstract.Value = SetAbstract; // remove any function mappings if we are setting this to abstract if (SetAbstract) { var etms = new List<EntityTypeMapping>(); etms.AddRange(EntityType.GetAntiDependenciesOfType<EntityTypeMapping>()); for (var i = etms.Count - 1; i >= 0; i--) { var etm = etms[i]; if (etm != null && etm.Kind == EntityTypeMappingKind.Function) { DeleteEFElementCommand.DeleteInTransaction(cpc, etm); } } } XmlModelHelper.NormalizeAndResolve(EntityType); }
protected override void InvokeInternal(CommandProcessorContext cpc) { var cmd = new UpdateDefaultableValueCommand<string>(_typeAccess, _newValue); CommandProcessor.InvokeSingleCommand(cpc, cmd); if (ModelConstants.CodeGenerationAccessInternal.Equals(_newValue, StringComparison.Ordinal)) { var cet = _typeAccess.GetParentOfType(typeof(ConceptualEntityType)) as ConceptualEntityType; Debug.Assert(null != cet, "parent of _typeAccess should be of type " + typeof(ConceptualEntityType).FullName); if (null != cet) { // Note: it is valid for the EntitySet to be null var ces = cet.EntitySet as ConceptualEntitySet; if (null != ces) { var entitySetGetterAccess = ces.GetterAccess.Value; if (ModelConstants.CodeGenerationAccessPublic.Equals(entitySetGetterAccess) || ModelConstants.CodeGenerationAccessProtected.Equals(entitySetGetterAccess)) { // new value is Internal and EntitySet's existing value is Public or Protected // so need to also update the GetterAccess attribute on the EntitySet // (otherwise will get runtime error 6036) var cmd2 = new UpdateDefaultableValueCommand<string>(ces.GetterAccess, _newValue); CommandProcessor.InvokeSingleCommand(cpc, cmd2); } } } } }
protected override void InvokeInternal(CommandProcessorContext cpc) { // check ModificationFunction or ComplexProperty parent exists Debug.Assert( _parentModificationFunction != null || _parentComplexProperty != null, "Must have either a ModificationFunction or a ComplexProperty parent to house this ComplexProperty"); if (_parentModificationFunction == null && _parentComplexProperty == null) { throw new CannotLocateParentItemException(); } // check both ModificationFunction and ComplexProperty parents don't exist Debug.Assert( _parentModificationFunction == null || _parentComplexProperty == null, "Must not have both a ModificationFunction and a ComplexProperty parent to house this ComplexProperty"); if (_parentModificationFunction != null && _parentComplexProperty != null) { throw new CannotLocateParentItemException(); } if (_parentModificationFunction != null) { _createdProperty = CreateComplexPropertyUsingModificationFunction(_parentModificationFunction, _property); } else if (_parentComplexProperty != null) { _createdProperty = CreateComplexPropertyUsingComplexProperty(_parentComplexProperty, _property); } Debug.Assert(_createdProperty != null, "Failed to create a FunctionComplexProperty"); }
internal PropagateStoreGeneratedPatternToStorageModel( CommandProcessorContext cpc, StorageProperty storageProperty, bool propagateNoneSGP) { _cpc = cpc; _storageProperty = storageProperty; _propagateNoneSGP = propagateNoneSGP; }
protected override void InvokeInternal(CommandProcessorContext cpc) { // if the DesignerInfoPropertySet doesn't exist then we need to create it. if (_designerInfo.PropertySet == null) { _designerInfo.PropertySet = new DesignerInfoPropertySet(_designerInfo, null); } // if the DesignerProperty doesn't exist then we need to create it. DesignerProperty designerProperty; if (!_designerInfo.PropertySet.TryGetDesignerProperty(_name, out designerProperty)) { designerProperty = new DesignerProperty(_designerInfo.PropertySet, null); designerProperty.LocalName.Value = _name; _designerInfo.PropertySet.AddDesignerProperty(_name, designerProperty); } // First let's check make sure any non-valid values are caught up the stack if (!designerProperty.ValueAttr.IsValidValue(_value)) { throw new CommandValidationFailedException( String.Format(CultureInfo.CurrentCulture, Resources.NonValidDesignerProperty, _value, _name)); } // now we update the value of the designer property var cmdUpdateDefaultableValue = new UpdateDefaultableValueCommand<string>(designerProperty.ValueAttr, _value); CommandProcessor.InvokeSingleCommand(cpc, cmdUpdateDefaultableValue); // normalize and resolve the entire DesignerInfo XmlModelHelper.NormalizeAndResolve(_designerInfo); }
protected override void InvokeInternal(CommandProcessorContext cpc) { // check that we have an existing artifact var service = cpc.EditingContext.GetEFArtifactService(); var existingArtifact = service.Artifact as EntityDesignArtifact; if (null == existingArtifact) { Debug.Fail("Null Artifact in ReplaceSsdlCommand.InvokeInternal()"); return; } // replace the old SSDL with the new ReplaceSsdl(cpc, existingArtifact, _newSsdlReader); // replace the old MSL with the new ReplaceMsl(cpc, existingArtifact, _newMslReader); // normalize and resolve the StorageModel XmlModelHelper.NormalizeAndResolve(existingArtifact.StorageModel); Debug.Assert(EFElementState.Resolved == existingArtifact.StorageModel.State, "StorageModel State should be Resolved"); // normalize and resolve the MappingModel XmlModelHelper.NormalizeAndResolve(existingArtifact.MappingModel); Debug.Assert(EFElementState.Resolved == existingArtifact.MappingModel.State, "MappingModel State should be Resolved"); }
protected override void InvokeInternal(CommandProcessorContext cpc) { var nExistingTypeShapeCount = _entity.GetAntiDependenciesOfType<EntityTypeShape>().Count(ets => ets.Diagram.Id == _diagram.Id.Value); Debug.Assert( nExistingTypeShapeCount == 0, "There is already Entity Type Shape for entity :" + _entity.Name + " in the diagram " + _diagram.Name); if (nExistingTypeShapeCount == 0) { var shape = new EntityTypeShape(_diagram, null); _diagram.AddEntityTypeShape(shape); shape.EntityType.SetRefName(_entity); shape.Width.Value = DEFAULTWIDTH; // The DSL will set the correct locations for the shapes at a later point, but we need to provide initial values for X and Y in the meantime // so that we can construct the shape. We're using random numbers here to ensure that if the DSL fails for some reason, new shapes do not // stack directly on top of each other. shape.PointX.Value = _rand.NextDouble() * 12.0; shape.PointY.Value = _rand.NextDouble() * 32.0; if (_fillColor != EntityDesignerDiagramConstant.EntityTypeShapeDefaultFillColor) { shape.FillColor.Value = _fillColor; } XmlModelHelper.NormalizeAndResolve(shape); _created = shape; } }
/// <summary> /// We override this method because we need to do some extra things before /// the normal PreInvoke gets called and our antiDeps are removed /// </summary> /// <param name="cpc"></param> protected override void PreInvoke(CommandProcessorContext cpc) { // remove the type of all related complex properties (so they won't get deleted) foreach (var property in EFElement.GetAntiDependenciesOfType<ComplexConceptualProperty>()) { foreach (var cp in property.GetAntiDependenciesOfType<ComplexProperty>()) { // also delete all related ComplexProperty mappings DeleteInTransaction(cpc, cp); } // rebind property.ComplexType to what it is bound to now. This adds a change to that SingleItemBinding // to the list of actions that this command takes (but note that its RefValue does not change). // This is important so that if Undo is called on this command that SingleItemBinding will be rebound back // to the re-added ComplexType. It is likely that this command will also delete ComplexProperty mappings (see just above). // If an Undo happens the resolve step for the ScalarProperty children of those mappings will fail if at // that time the property.ComplexType SingleItemBinding is not resolved. if (property.ComplexType.Target != null) { // have to set to null and then reset because just setting to the existing value is shortcircuited out property.ComplexType.SetRefName(null); property.ComplexType.SetRefName(property.ComplexType.Target); property.ComplexType.Rebind(); } // unbind the property.ComplexType but leave the reference pointing to the soon to be non-existent ComplexType // so that the error message tells the user what has happened (and what they can do to fix it) property.ComplexType.Unbind(); _complexPropertiesToResolve.Add(property); } base.PreInvoke(cpc); }
/// <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; }
protected override void InvokeInternal(CommandProcessorContext cpc) { if (String.IsNullOrEmpty(_summaryText)) { if (_efElement.Documentation != null && _efElement.Documentation.Summary != null) { DeleteEFElementCommand.DeleteInTransaction(cpc, _efElement.Documentation.Summary); // if the documentation node is empty, delete it if (_efElement.Documentation.LongDescription == null) { DeleteEFElementCommand.DeleteInTransaction(cpc, _efElement.Documentation); } } } else { if (_efElement.Documentation == null) { _efElement.Documentation = new Documentation(_efElement, null); } if (_efElement.Documentation.Summary == null) { _efElement.Documentation.Summary = new Summary(_efElement.Documentation, null); } _efElement.Documentation.Summary.Text = _summaryText; XmlModelHelper.NormalizeAndResolve(_efElement); } }
protected override void InvokeInternal(CommandProcessorContext cpc) { // safety check, this should never be hit Debug.Assert(Property != null, "InvokeInternal is called when Property is null."); if (Property == null) { throw new InvalidOperationException("InvokeInternal is called when Property is null."); } var cmd = new UpdateDefaultableValueCommand<string>(Property.StoreGeneratedPattern, SgpValue); CommandProcessor.InvokeSingleCommand(cpc, cmd); // ensure view keys are propagated from C-side to S-side var cet = Property.EntityType as ConceptualEntityType; if (cet != null) { PropagateViewKeysToStorageModel.AddRule(cpc, cet); } // ensure StoreGeneratedPattern is propagated from C-side to S-side // unless we are part of an Update Model txn in which case there is no need // as the whole artifact has this integrity check applied by UpdateModelFromDatabaseCommand if (EfiTransactionOriginator.UpdateModelFromDatabaseId != cpc.OriginatorId) { var cProp = Property as ConceptualProperty; Debug.Assert(cProp != null, "expected Property of type ConceptualProperty, instead got type " + Property.GetType().FullName); if (cProp != null) { PropagateStoreGeneratedPatternToStorageModel.AddRule(cpc, cProp, true); } } }
protected override void InvokeInternal(CommandProcessorContext cpc) { if (!string.IsNullOrEmpty(Role) && !string.Equals(End.Role.Value, Role, StringComparison.Ordinal)) { // TODO: should this command be enqueued in the command processor? RenameCommand c = new EntityDesignRenameCommand(End, Role, true); CommandProcessor.InvokeSingleCommand(cpc, c); // bug 563525: we need to update EndProperties within AssociationSetMappings if the AssociationEnd changes. // we update the "Role" of an AssociationSetEnd in the RenameCommand but the SingleItemBinding that we have to update // that is bound to the AssociationSetEnd is unique to this situation; it is not technically a "refactor rename". var associationSetEnd = End.GetAntiDependenciesOfType<AssociationSetEnd>().FirstOrDefault(); if (associationSetEnd != null) { // we need to renormalize the associationSetEnd, since the role name will have changed. XmlModelHelper.NormalizeAndResolve(associationSetEnd); var endPropertiesInAssocSetMappings = associationSetEnd.GetAntiDependenciesOfType<EndProperty>(); foreach (var endProperty in endPropertiesInAssocSetMappings) { endProperty.Name.SetRefName(associationSetEnd); CheckArtifactBindings.ScheduleBindingsForRebind(cpc, new HashSet<ItemBinding> { endProperty.Name }); } } } }
protected override void InvokeInternal(CommandProcessorContext cpc) { if (_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; // check if entity is in the model _createdEntity = artifact.ArtifactSet.LookupSymbol(_clipboardEntity.NormalizedName) as EntityType; if (_diagram != null && _createdEntity != null && _createdEntity is ConceptualEntityType) { if (_createdEntity.GetAntiDependenciesOfType<EntityTypeShape>().Count(ets => ets.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, _createdEntity as ConceptualEntityType, _clipboardEntity.EntityTypeShapeFillColor, false); return; } } CreateEntityCopyInModel(cpc); }
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 entityType = viewModel.ModelXRef.GetExisting(_property.EntityType) as Model.Entity.EntityType; Debug.Assert(entityType != null); Model.Entity.Property property = null; if (_property is ScalarProperty) { property = CreatePropertyCommand.CreateDefaultProperty(cpc, _property.Name, entityType); var scalarProperty = _property as ScalarProperty; if (scalarProperty != null && scalarProperty.EntityKey) { CommandProcessor.InvokeSingleCommand(cpc, new SetKeyPropertyCommand(property, true)); } } else { property = CreateComplexPropertyCommand.CreateDefaultProperty(cpc, _property.Name, entityType); } viewModel.ModelXRef.Add(property, _property, viewModel.EditingContext); } }
internal static void ScheduleChildAntiDependenciesForRebinding(CommandProcessorContext cpc, EFObject efObject) { // identify any binding that was referencing this symbol, and add it to the list of things to rebind. var visitor = new AntiDependencyCollectorVisitor(); visitor.Traverse(efObject); ScheduleBindingsForRebind(cpc, visitor.AntiDependencyBindings); }
protected override void InvokeInternal(CommandProcessorContext cpc) { Debug.Assert(_step > 0, "Parameter step value is not valid. The value must be greater than 0."); if (_step > 0) { // Skip moving property up if the property is already the first property. if (_moveDirection == MoveDirection.Up && _property.PreviousSiblingInPropertyXElementOrder != null) { var previousSibling = _property.PreviousSiblingInPropertyXElementOrder; for (var i = 1; i < _step && previousSibling.PreviousSiblingInPropertyXElementOrder != null; i++) { previousSibling = previousSibling.PreviousSiblingInPropertyXElementOrder; } _property.MoveTo(new InsertPropertyPosition(previousSibling, true)); } // Skip moving property down if the property is already the last property. else if (_moveDirection == MoveDirection.Down && _property.NextSiblingInPropertyXElementOrder != null) { var nextSibling = _property.NextSiblingInPropertyXElementOrder; for (var i = 1; i < _step && nextSibling.NextSiblingInPropertyXElementOrder != null; i++) { nextSibling = nextSibling.NextSiblingInPropertyXElementOrder; } _property.MoveTo(new InsertPropertyPosition(nextSibling, false)); } } }
protected override void InvokeInternal(CommandProcessorContext cpc) { // if don't have an ECM yet, go create one if (_entityContainerMapping == null) { var cmd = new CreateEntityContainerMappingCommand(_entitySet.Artifact); CommandProcessor.InvokeSingleCommand(cpc, cmd); _entityContainerMapping = cmd.EntityContainerMapping; } Debug.Assert(_entityContainerMapping != null, "_entityContainerMapping should not be null"); if (_entityContainerMapping == null) { throw new CannotLocateParentItemException(); } // create the ESM var esm = new EntitySetMapping(_entityContainerMapping, null); esm.Name.SetRefName(_entitySet); _entityContainerMapping.AddEntitySetMapping(esm); XmlModelHelper.NormalizeAndResolve(esm); _created = esm; }
/// <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> internal static void DeleteInTransaction(CommandProcessorContext cpc, EFElement element) { var cmd = element.GetDeleteCommand(); DeleteInTransaction(cpc, cmd, true); }
protected override void InvokeInternal(CommandProcessorContext cpc) { if (_efElements != null) { foreach (var efElement in _efElements) { // -------------------------------------------------------------------------------- // | EF Element Type | Diagram shape type | // -------------------------------------------------------------------------------- // | Conceptual Entity Type Entity Type Shape | // | Association Association Connector | // | Association Set Association Connector | // | Entity Set Entity Type Shapes for all ET in the set | // | Property Property's entity type shape | // -------------------------------------------------------------------------------- var entityType = efElement as ConceptualEntityType; var association = efElement as Association; var entitySet = efElement as EntitySet; var associationSet = efElement as AssociationSet; if (efElement is Property) { entityType = efElement.GetParentOfType(typeof(ConceptualEntityType)) as ConceptualEntityType; } if (associationSet != null && associationSet.Association.Status == BindingStatus.Known) { association = associationSet.Association.Target; } if (entityType != null) { CreateEntityTypeShapeCommand.CreateEntityTypeShapeAndConnectorsInDiagram( cpc, _diagram, entityType, _createRelatedEntities); } else if (association != null) { Debug.Assert( association.AssociationEnds().Count == 2, "Received incorrect number of AssociationEnds (" + association.AssociationEnds().Count + ") for Association " + association.ToPrettyString() + " should be 2."); var assocEnds = association.AssociationEnds(); var assocEnd1 = assocEnds[0]; var assocEnd2 = assocEnds[1]; if (assocEnd1.Type.Status == BindingStatus.Known && assocEnd2.Type.Status == BindingStatus.Known) { CreateEntityTypeShapeCommand.CreateEntityTypeShapeAndConnectorsInDiagram( cpc, _diagram, assocEnd1.Type.Target as ConceptualEntityType, _createRelatedEntities); // Check whether the association is self association or not. // If it is a self association, then we can skip creating the shape for the second associationEnd's entity type // since both association-ends point to the same entity type. if (assocEnd1.Type.Target != assocEnd2.Type.Target) { CreateEntityTypeShapeCommand.CreateEntityTypeShapeAndConnectorsInDiagram( cpc, _diagram, assocEnd2.Type.Target as ConceptualEntityType, _createRelatedEntities); } } } else if (entitySet != null) { foreach (var et in entitySet.GetEntityTypesInTheSet()) { CreateEntityTypeShapeCommand.CreateEntityTypeShapeAndConnectorsInDiagram( cpc, _diagram, et as ConceptualEntityType, _createRelatedEntities); } } else { Debug.Fail("Unable to create diagram shape for EFElement with type:" + efElement.GetType().Name); } } } }
protected override void InvokeInternal(CommandProcessorContext cpc) { // safety check, this should never be hit Debug.Assert(ParentComplexType != null, "InvokeInternal is called when ParentComplexType is null."); if (ParentComplexType == null) { throw new InvalidOperationException("InvokeInternal is called when ParentComplexType is null"); } Debug.Assert(!(Type == null && ComplexType == null), "InvokeInternal is called when Type or ComplexType is null."); if (Type == null && ComplexType == null) { throw new InvalidOperationException("InvokeInternal is called when Type and ComplexType is null"); } // check for uniqueness string msg; if (!ModelHelper.ValidateComplexTypePropertyName(ParentComplexType, Name, true, out msg)) { throw new CommandValidationFailedException(msg); } // check for ComplexType circular definition if (ComplexType != null) { if (ModelHelper.ContainsCircularComplexTypeDefinition(ParentComplexType, ComplexType)) { throw new CommandValidationFailedException( String.Format( CultureInfo.CurrentCulture, Resources.Error_CircularComplexTypeDefinitionOnAdd, ComplexType.LocalName.Value)); } } // create the property Property property = null; if (Type != null) { var conceptualProperty = new ConceptualProperty(ParentComplexType, null); conceptualProperty.ChangePropertyType(Type); property = conceptualProperty; } else { var complexProperty = new ComplexConceptualProperty(ParentComplexType, null); complexProperty.ComplexType.SetRefName(ComplexType); property = complexProperty; } Debug.Assert(property != null, "property should not be null"); if (property == null) { throw new ItemCreationFailureException(); } // set the name and add to the parent entity property.LocalName.Value = Name; ParentComplexType.AddProperty(property); // set other attributes of the property if (Nullable != null) { property.Nullable.Value = (Nullable.Value ? BoolOrNone.TrueValue : BoolOrNone.FalseValue); } XmlModelHelper.NormalizeAndResolve(property); _createdProperty = property; }
/// <summary> /// Initializes a new instance of CommandProcessor. /// </summary> /// <param name="cpc">CommandProcessorContext.</param> /// <param name="commands">The commands are placed in the queue</param> internal CommandProcessor(CommandProcessorContext cpc, params Command[] commands) : this(cpc, true, commands) { }
/// <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 Debug.Assert(Property != null, "InvokeInternal is called when property is null."); if (Property == null) { throw new InvalidOperationException("InvokeInternal is called when Property is null."); } if (Property.IsKeyProperty == IsKey) { // no change needed return; } if (IsKey) { if (Property.EntityType.Key == null) { Property.EntityType.Key = new Key(Property.EntityType, null); } // make the key property non-nullable Property.Nullable.Value = BoolOrNone.FalseValue; Property.EntityType.Key.AddPropertyRef(Property); // normalize & resolve the key property XmlModelHelper.NormalizeAndResolve(Property.EntityType.Key); } else { var keyElement = Property.EntityType.Key; Debug.Assert(keyElement != null, "keyElement should not be null"); if (keyElement != null) { keyElement.RemovePropertyRef(Property); if (!keyElement.Children.Any()) { keyElement.Delete(); } else { XmlModelHelper.NormalizeAndResolve(keyElement); } } // if we are changing from key to non-key and this key is referenced by a principal end of // a ref constraint, then we want to delete that entry in the ref constraint if (IsKey == false && _deletePrincipalRCRefs) { foreach (var pref in Property.GetAntiDependenciesOfType <PropertyRef>()) { if (pref != null) { var role = pref.Parent as ReferentialConstraintRole; if (role != null) { var rc = role.Parent as ReferentialConstraint; if (rc != null && rc.Principal == role) { // property ref on a principal end, so delete it DeleteEFElementCommand.DeleteInTransaction(cpc, pref); } } } } } } var cet = Property.EntityType as ConceptualEntityType; if (cet != null) { PropagateViewKeysToStorageModel.AddRule(cpc, cet); } }
protected override void InvokeInternal(CommandProcessorContext cpc) { if (null == _conceptualEntityModel) { Debug.Fail("Null ConceptualEntityModel"); return; } var artifact = _conceptualEntityModel.Artifact; if (null == artifact) { Debug.Fail("Null Artifact"); return; } var artifactSet = artifact.ArtifactSet; if (null == artifactSet) { Debug.Fail("Null ArtifactSet"); return; } // check to see if the new alias is valid if (_conceptualEntityModel.Alias.IsValidValue(_newAlias)) { var previousAlias = _conceptualEntityModel.Alias.Value; // its not an error not to have a previous Alias - if so just // update the attribute itself if (!string.IsNullOrEmpty(previousAlias)) { // lookup the namespace that the Alias maps to var previousConceptualNamespace = _conceptualEntityModel.Namespace.Value; if (string.IsNullOrEmpty(previousConceptualNamespace)) { Debug.Fail("Null or empty conceptual namespace"); return; } // find all Symbols in the ArtifactSet which have first part // equal to existing previousConceptualNamespace (if it was // referred to in the XML as 'Alias.XXX' then it will be in // the symbol table as 'Namespace.XXX') var allElementsWithConceptualNamespaceSymbol = artifactSet.GetElementsContainingFirstSymbolPart(previousConceptualNamespace); // change all references which include the alias to the new alias foreach (var element in allElementsWithConceptualNamespaceSymbol) { var itemBindings = element.GetDependentBindings(); foreach (var itemBinding in itemBindings) { if (null == itemBinding.GetParentOfType(typeof(ConceptualEntityModel))) { // itemBinding is not in the Conceptual Model - conceptual // Alias can only be referenced within the Conceptual Model // so ignore this ItemBinding continue; } itemBinding.UpdateRefNameAliases(previousAlias, _newAlias); } } } // now update the alias attribute itself _conceptualEntityModel.Alias.Value = _newAlias; // symbols need to be recalculated throughout the // CSDL, bindings need to be rebound ... XmlModelHelper.NormalizeAndResolve(_conceptualEntityModel); } else { // if not a valid namespace, throw an error message var msg = string.Format(CultureInfo.CurrentCulture, Resources.INVALID_NC_NAME_CHAR, _newAlias); throw new CommandValidationFailedException(msg); } }
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; } }
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; }
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> /// This will create a transaction if there isn't one already. If the CommandProcessorContext is already /// tracking a transaction, then a new one is NOT created. This specific overload allows modifying the /// command before invoking it (i.e. adding a PostInvokeEvent) /// </summary> /// <param name="cpc"></param> /// <param name="cmd"></param> internal static void DeleteInTransaction(CommandProcessorContext cpc, DeleteEFElementCommand cmd) { DeleteInTransaction(cpc, cmd, true); }
/// <summary> /// This will create a transaction if there isn't one already. If the CommandProcessorContext is already /// tracking a transaction, then a new one is NOT created. /// </summary> /// <param name="cpc"></param> /// <param name="element">The EFElement to delete</param> /// <param name="rebindAllBindings">Control whether all bindings in the artifact should be rebound</param> internal static void DeleteInTransaction(CommandProcessorContext cpc, DeleteEFElementCommand cmd, bool rebindAllBindings) { cmd.RebindAllBindings = rebindAllBindings; CommandProcessor.InvokeSingleCommand(cpc, cmd); }
internal static void CreateEntityTypeShapeAndConnectorsInDiagram( CommandProcessorContext cpc, Diagram diagram, ConceptualEntityType entity, bool createRelatedEntityTypeShapes) { CreateEntityTypeShapeAndConnectorsInDiagram( cpc, diagram, entity, EntityDesignerDiagramConstant.EntityTypeShapeDefaultFillColor, createRelatedEntityTypeShapes); }
/// <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); }
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); } } } } }
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) { 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); } } }
private void PostProcessUpdate(CommandProcessorContext cpc, EfiTransaction tx, bool artifactInitiallyDirty) { var setUndoScope = false; try { // process those checks that need to run in the originating xact while (cpc.IntegrityChecks.Count > 0) { // peek for the next check and invoke it, don't dequeue it so we // won't add dupes and recurse forever var check = cpc.IntegrityChecks.Peek(); check.Invoke(); // now pop it off the queue cpc.IntegrityChecks.Dequeue(); } if (cpc.EditingContext.ParentUndoUnitStarted == false) { cpc.EditingContext.ParentUndoUnitStarted = true; cpc.Artifact.XmlModelProvider.BeginUndoScope(cpc.EfiTransaction.Name); setUndoScope = true; } if (_shouldNotifyObservers) { cpc.Artifact.ModelManager.BeforeCommitChangeGroups(cpc); } // Do not mark the artifact as clean if the artifact was initially dirty before commands // were executed... otherwise we may lose information like diagram layout and configurations. // Also, translation rules can perform immediate changes to configurations which will dirty the artifact // but are not recorded through the enqueued commands. So we should not set the artifact to clean in this case. tx.Commit(!artifactInitiallyDirty); cpc.DisposeTransaction(); #if DEBUG var visitor = cpc.Artifact.GetVerifyModelIntegrityVisitor(true, true, true, true, true); visitor.Traverse(cpc.Artifact); if (visitor.ErrorCount > 0) { Debug.WriteLine("Model Integrity Verifier found " + visitor.ErrorCount + " error(s):"); Debug.WriteLine(visitor.AllSerializedErrors); Debug.Assert( false, "Model Integrity Verifier found " + visitor.ErrorCount + " error(s). See the Debug console for details."); } #endif if (_shouldNotifyObservers) { cpc.Artifact.ModelManager.RouteChangeGroups(); } else { // Changegroups have been recorded in the model manager; // if we don't clear them they will be routed on the next observable transaction. cpc.Artifact.ModelManager.ClearChangeGroups(); } } finally { if (setUndoScope) { cpc.Artifact.XmlModelProvider.EndUndoScope(); cpc.EditingContext.ParentUndoUnitStarted = false; } } }
protected override void InvokeInternal(CommandProcessorContext cpc) { Debug.Assert( ModeValue == Mode.EntityType || ModeValue == Mode.MappingFragment || ModeValue == Mode.ComplexProperty, "Unknown mode set in CreateFragmentScalarPropertyCommand"); if (ModeValue == Mode.EntityType) { // safety check, this should never be hit if (ConceptualEntityType == null || Property == null || TableColumn == null) { throw new ArgumentNullException(); } _sp = CreateScalarPropertyUsingEntity( cpc, ConceptualEntityType, Property, TableColumn); } else if (ModeValue == Mode.ComplexProperty) { // safety check, this should never be hit if (ComplexProperty == null || Property == null || TableColumn == null) { throw new ArgumentNullException(); } _sp = CreateScalarPropertyUsingComplexProperty(ComplexProperty, Property, TableColumn); } else { // safety check, this should never be hit if (_mappingFragment == null || Property == null || TableColumn == null) { throw new ArgumentNullException(); } _sp = CreateScalarPropertyUsingFragment(_mappingFragment, Property, TableColumn); } if (_sp.MappingFragment != null && _sp.MappingFragment.EntityTypeMapping != null && _sp.MappingFragment.EntityTypeMapping.FirstBoundConceptualEntityType != null) { PropagateViewKeysToStorageModel.AddRule(cpc, _sp.MappingFragment.EntityTypeMapping.FirstBoundConceptualEntityType); // Also add the integrity check to propagate the StoreGeneratedPattern value to the // S-side (may be altered by property being/not being mapped) unless we are part // of an Update Model txn in which case there is no need as the whole artifact has // this integrity check applied by UpdateModelFromDatabaseCommand if (EfiTransactionOriginator.UpdateModelFromDatabaseId != cpc.OriginatorId && _sp.Name != null && _sp.Name.Target != null) { var cProp = _sp.Name.Target as ConceptualProperty; Debug.Assert( cProp != null, " ScalarProperty should have Name target with type ConceptualProperty, instead got type " + _sp.Name.Target.GetType().FullName); if (cProp != null) { PropagateStoreGeneratedPatternToStorageModel.AddRule(cpc, cProp, true); } } } }
protected override void InvokeInternal(CommandProcessorContext cpc) { _property.Relationship.SetRefName(_association); _property.Relationship.Rebind(); Debug.Assert( (_property.Relationship.Status == BindingStatus.Known || (_association == null && _property.Relationship.Status == BindingStatus.Undefined)), "Rebind for the NavigationProperty failed"); if (_association != null) { if (_end1 == null || _end2 == null) { var associationEnds = _association.AssociationEnds(); Debug.Assert(associationEnds.Count < 3, "AssociationEnds are >= 3"); _end1 = associationEnds.Where( r => r.Type != null && r.Type.Status == BindingStatus.Known && r.Type.Target == _property.Parent) .FirstOrDefault(); _end2 = associationEnds.Where( r => r.Type != null && r.Type.Status == BindingStatus.Known && ((r.Type.Target != _property.Parent) || (r.Type.Target == _property.Parent && r != _end1))).FirstOrDefault(); } // updating association's multiplicity value as opposed to multiplicity itself. if (string.IsNullOrEmpty(_multiplicity) && _end2 != null) { _multiplicity = _end2.Multiplicity.Value; } } else { // resets end points when we get a null association _end1 = null; _end2 = null; } // rebinds association properties. _property.FromRole.SetRefName(_end1); _property.FromRole.Rebind(); _property.ToRole.SetRefName(_end2); _property.ToRole.Rebind(); if (_property.ToRole.Status == BindingStatus.Known && string.Compare(_property.ToRole.Target.Multiplicity.Value, _multiplicity, StringComparison.OrdinalIgnoreCase) != 0) { if (_property.Relationship.Status == BindingStatus.Known) { var association = _property.Relationship.Target; _property.ToRole.Target.Multiplicity.Value = _multiplicity; if (association != null && association.AssociationSet != null && association.AssociationSet.AssociationSetMapping != null) { EnforceAssociationSetMappingRules.AddRule(cpc, association.AssociationSet.AssociationSetMapping); } } } }
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) { ModelHelper.SetConditionPredicate(Condition, _isNull, _conditionValue); XmlModelHelper.NormalizeAndResolve(Condition); }
protected override void InvokeInternal(CommandProcessorContext cpc) { // check that we have an existing artifact var service = cpc.EditingContext.GetEFArtifactService(); var existingArtifact = service.Artifact as EntityDesignArtifact; Debug.Assert(existingArtifact != null, "Null Artifact"); if (null == existingArtifact) { return; } // check that the _new_ artifact's StorageEntityModel exists and has an underlying XObject if (null == _newArtifactStorageEntityModel || null == _newArtifactStorageEntityModel.XObject) { Debug.Fail("new artifact StorageModel was null or has null XObject"); return; } // save off the old storage model namespace, the old storage Entity Model // and the old storage Entity Container name string previousStorageModelNamespace = null; StorageEntityModel previousStorageEntityModel = null; string previousStorageEntityContainerName = null; if (null != existingArtifact.StorageModel) { previousStorageEntityModel = existingArtifact.StorageModel; if (null != previousStorageEntityModel.Namespace && !string.IsNullOrEmpty(previousStorageEntityModel.Namespace.Value)) { previousStorageModelNamespace = previousStorageEntityModel.Namespace.Value; } if (null != previousStorageEntityModel.FirstEntityContainer && null != previousStorageEntityModel.FirstEntityContainer.LocalName && !string.IsNullOrEmpty(previousStorageEntityModel.FirstEntityContainer.LocalName.Value)) { previousStorageEntityContainerName = previousStorageEntityModel.FirstEntityContainer.LocalName.Value; } } // for any S-side objects which have been renamed, re-target the MSL // which targets them in preparation for their replacement below RetargetMappingsForRenamedStorageObjects(previousStorageEntityModel, _newArtifactStorageEntityModel); // Recurse through the MappingModel updating any references to the old S-side Namespace // if different from the new one (must be done before SSDL is replaced which will // unbind all the references) if (existingArtifact.MappingModel != null && _newArtifactStorageEntityModel != null && _newArtifactStorageEntityModel.Namespace != null && !string.IsNullOrEmpty(_newArtifactStorageEntityModel.Namespace.Value) && !_newArtifactStorageEntityModel.Namespace.Value.Equals(previousStorageModelNamespace, StringComparison.CurrentCulture)) { RecursivelyReplaceStorageNamespaceRefs( existingArtifact.MappingModel, previousStorageModelNamespace, _newArtifactStorageEntityModel.Namespace.Value); } // replace the old SSDL with the new ReplaceSsdl(cpc, existingArtifact, _newArtifactStorageEntityModel.XElement); // update the Mapping Model to reference the new SSDL UpdateMappingModel(existingArtifact, previousStorageEntityContainerName); }
protected override void InvokeInternal(CommandProcessorContext cpc) { base.InvokeInternal(cpc); }
internal CommandEventArgs(CommandProcessorContext cpc) { CommandProcessorContext = cpc; }
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; } } }
/// <summary> /// If this element has any children that have unresolved references /// or has itself an unresolved reference then Delete the element /// NB: Be warned this method is destructive. If you have unbound /// elements for whatever reason then those elements will be removed. /// </summary> private static void RecursiveDeleteUnboundElements(CommandProcessorContext cpc, EFElement efElement) { var mappingCondition = efElement as Condition; var queryView = efElement as QueryView; if (mappingCondition != null) { // A Mapping Condition is special because it will // only ever have 1 bound child out of 2 var children = efElement.Children.ToArray(); var anyOneOfChildrenIsBound = children.OfType <ItemBinding>().Any(itemBinding => itemBinding.Resolved); if (!anyOneOfChildrenIsBound) { DeleteEFElementCommand.DeleteInTransaction(cpc, efElement); } return; } else if (queryView != null) { // QueryView elements have a TypeName attribute, but it is optional and // so the QueryView should not be deleted even if the TypeName attribute // is not in a Resolved state return; } else { // cannot use IEnumerable directly as we are potentially // deleting from the returned collection var children = new List <EFObject>(efElement.Children); // remove any children which are optional (and hence not being resolved does not require a delete) var cp = efElement as ComplexProperty; if (cp != null) { // TypeName binding in ComplexProperty is optional and can be unresolved, so remove it from the check list children.Remove(cp.TypeName); } var mf = efElement as ModificationFunction; if (mf != null) { children.Remove(mf.RowsAffectedParameter); } // loop over children and recursively delete foreach (var child in children) { var efElementChild = child as EFElement; var itemBindingChild = child as ItemBinding; if (efElementChild != null) { RecursiveDeleteUnboundElements(cpc, efElementChild); } else if (itemBindingChild != null) { if (!itemBindingChild.Resolved) { DeleteEFElementCommand.DeleteInTransaction(cpc, efElement); return; } } } } }
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; } }
protected override void InvokeInternal(CommandProcessorContext cpc) { _delegateCommandCallback(); }
/// <summary> /// Update function import return type if requested. /// </summary> private void UpdateFunctionImportReturnType(CommandProcessorContext cpc) { if (ChangeReturnType) { // figure out if we are using a complex type, an entity type, primitive type or none as the return type var complexType = ReturnSingleType as ComplexType; var entityType = ReturnSingleType as EntityType; // if returnTypeStringValue is not null, the value could be "None" or the string representation of primitive types (for example: "string", "Int16"). var returnTypeStringValue = ReturnSingleType as string; // Only delete type-mapping if the function-import's return-type does not match type-mapping's type. var functionImportMapping = FunctionImport.FunctionImportMapping; if (functionImportMapping != null && functionImportMapping.ResultMapping != null) { foreach (var typeMapping in functionImportMapping.ResultMapping.TypeMappings().ToList()) { // If the old type mapping is FunctionImportComplexTypeMapping and function import does not return a complex type // or return a different complex type. if (typeMapping is FunctionImportComplexTypeMapping && (complexType == null || !String.Equals(typeMapping.TypeName.Target.DisplayName, complexType.DisplayName, StringComparison.CurrentCulture))) { DeleteEFElementCommand.DeleteInTransaction(cpc, typeMapping); } // If the old type mapping is FunctionImportEntityTypeMapping and function import does not return an entity type // or return a different entity type. else if (typeMapping is FunctionImportEntityTypeMapping && (entityType == null || !String.Equals(typeMapping.TypeName.Target.DisplayName, entityType.DisplayName, StringComparison.CurrentCulture))) { DeleteEFElementCommand.DeleteInTransaction(cpc, typeMapping); } } // If ResultMapping does not contain any type mappings, delete it. if (functionImportMapping.ResultMapping.TypeMappings().Count == 0) { DeleteEFElementCommand.DeleteInTransaction(cpc, functionImportMapping.ResultMapping); } } // we won't do any equality checking here against the original function import's return type // because we would expend cycles determining the 'collection' string, etc. string updatedReturnTypeAsString = null; if (entityType != null) { // Return type could be a collection of EntityType, ComplexType or primitive type. // If we change from the return type from a complex type to an entity type, we need to remove the complex type binding in the function import. // Check if complex type binding is not null and reset it. if (FunctionImport.ReturnTypeAsComplexType != null) { FunctionImport.ReturnTypeAsComplexType.SetRefName(null); FunctionImport.ReturnTypeAsComplexType.Rebind(); } // if we are using an entity type, the return type is "Collection(entityType)" Debug.Assert(entityType.EntitySet != null, "Entity Type doesn't have an Entity Set we can use for the Function Import"); if (entityType.EntitySet != null) { FunctionImport.EntitySet.SetRefName(entityType.EntitySet); FunctionImport.EntitySet.Rebind(); FunctionImport.ReturnTypeAsEntityType.SetRefName(entityType); FunctionImport.ReturnTypeAsEntityType.Rebind(); } } else if (complexType != null) { // if we change from an entity type to any other type, we need to remove the EntitySet binding on the FunctionImport if (FunctionImport.EntitySet.RefName != null) { FunctionImport.EntitySet.SetRefName(null); FunctionImport.EntitySet.Rebind(); } FunctionImport.ReturnTypeAsComplexType.SetRefName(complexType); FunctionImport.ReturnTypeAsComplexType.Rebind(); } else { // Return type could be a collection of EntityType, ComplexType or primitive type. // If we change from the return type from a complex type to a primitive type, we need to remove the complex type binding in the function import. // Check if complex type binding is not null and reset it. if (FunctionImport.ReturnTypeAsComplexType != null) { FunctionImport.ReturnTypeAsComplexType.SetRefName(null); FunctionImport.ReturnTypeAsComplexType.Rebind(); } // if we change from an entity type to any other type, we need to remove the EntitySet binding on the FunctionImport if (FunctionImport.EntitySet.RefName != null) { FunctionImport.EntitySet.SetRefName(null); FunctionImport.EntitySet.Rebind(); } // if the new value is 'None' then set the return type to null if (returnTypeStringValue != Tools.XmlDesignerBase.Resources.NoneDisplayValueUsedForUX) { updatedReturnTypeAsString = String.Format( CultureInfo.InvariantCulture, FunctionImport.CollectionFormat, returnTypeStringValue); } // update the actual return type of the function import FunctionImport.ReturnTypeAsPrimitiveType.Value = updatedReturnTypeAsString; } } }