internal void BeforeCommitChangeGroups(CommandProcessorContext cpc) { var args = new EfiChangingEventArgs(cpc); if (BeforeModelChangesCommitted != null) { // now tell everyone that the changes are about to be committed BeforeModelChangesCommitted(this, args); } }
private void OnBeforeModelChangesCommitted(object sender, EfiChangingEventArgs e) { if (e.CommandProcessorContext != null) { var artifact = e.CommandProcessorContext.Artifact; if (_diagrams != null) { // Copy the current Xml changes over since we are going to modifying the transaction var xmlChangesCopy = new List <IXmlChange>(); var shapeChangeInfoSet = new HashSet <ShapeChangeInformation>(); foreach (var xmlChange in e.CommandProcessorContext.EfiTransaction.XmlChanges) { // if the changed node is whitespace, ignore it as we don't want to pick up false // annotations for it if (xmlChange.Node.NodeType == XmlNodeType.Text) { var text = xmlChange.Node as XText; var trimmedValue = text.Value.Trim(); if (String.IsNullOrEmpty(trimmedValue)) { continue; } } // Ignore changes to annotations var externalModelChange = new EFArtifact.ExternalXMLModelChange(xmlChange, artifact.ExpectEFObjectForXObject); if (externalModelChange.IsAnnotationChange(artifact.GetNamespaces())) { continue; } // Construct a fast-queryable lookup for the shape change information that already // exists in this transaction. The transaction may have already fired some rules that // injected shape (DiagramEFObjects) information into the transaction. The purpose // of this lookup is to skip duplicate additions/removals. var changedEFObject = externalModelChange.ChangedEFObject; if (changedEFObject != null) { var diagramObject = changedEFObject as ModelDiagram.BaseDiagramObject; if (diagramObject != null) { var changedEntityTypeShape = changedEFObject as EntityTypeShape; var changedAssociationConnector = changedEFObject as AssociationConnector; var changedInheritanceConnector = changedEFObject as InheritanceConnector; var shapeChangeInformation = new ShapeChangeInformation(); if (changedEntityTypeShape != null) { shapeChangeInformation.ModelEFObject = changedEntityTypeShape.EntityType.Target; } else if (changedAssociationConnector != null) { shapeChangeInformation.ModelEFObject = changedAssociationConnector.Association.Target; } else if (changedInheritanceConnector != null) { shapeChangeInformation.ModelEFObject = changedInheritanceConnector.EntityType.Target; } shapeChangeInformation.ChangeType = xmlChange.Action; Debug.Assert( diagramObject.Diagram != null, changedEFObject.ToPrettyString() + " doesn't belong to any diagram."); if (diagramObject.Diagram != null) { shapeChangeInformation.DiagramId = diagramObject.Diagram.Id; } shapeChangeInfoSet.Add(shapeChangeInformation); } } xmlChangesCopy.Add(xmlChange); } // Call resolve on the diagram objects in the model here. When the EDMX is being incrementally updated by some // external factor (for example, a database project in a by-ref edmx), there may be situations where the existing // diagram objects are not resolved yet. This means that when we try to create entity type shapes or association connectors // the logic assumes that there aren't any anti-dependencies of the model elements, so it adds duplicate shapes/connectors // which can affect the loading of the model later (it will hit DSL diagram validation logic). XmlModelHelper.NormalizeAndResolve(this); // If we see that an Association, EntityType, or EntityTypeBaseType has been added in the model // changes, then we create the subsequent diagram EFObjects (AssociationConnector, EntityTypeShape, // and InheritanceConnector). By creating them here, this will automatically push new changes onto the // Xml transaction foreach (var xmlChange in xmlChangesCopy) { var changedEFObject = ModelItemAnnotation.GetModelItem(xmlChange.Node); if (changedEFObject != null && ModelHelper.GetBaseModelRoot(changedEFObject) is ConceptualEntityModel) { var entityType = changedEFObject as ConceptualEntityType; var association = changedEFObject as Association; var baseType = changedEFObject as EntityTypeBaseType; foreach (var diagram in _diagrams) { if (entityType != null) { InjectEntityTypeShapeCommand( e.CommandProcessorContext, shapeChangeInfoSet, diagram, entityType, xmlChange.Action); } else if (association != null) { InjectAssociationConnectorCommand( e.CommandProcessorContext, shapeChangeInfoSet, diagram, association, xmlChange.Action); } else if (baseType != null) { InjectInheritanceConnectorCommand( e.CommandProcessorContext, shapeChangeInfoSet, diagram, baseType, xmlChange.Action); } } } } } } }