Example #1
0
        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);
            }
        }
Example #2
0
        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);
                                }
                            }
                        }
                    }
                }
            }
        }