Пример #1
0
        /// <summary>
        ///     Return true if there is diagram object that represents efelement/efobject in the diagram.
        /// </summary>
        /// <param name="efObject"></param>
        /// <returns></returns>
        internal bool IsEFObjectRepresentedInDiagram(EFObject efObject)
        {
            var entityTypesInDiagram = EntityTypeShapes.Select(ets => ets.EntityType.Target).ToList();

            var entityType     = efObject.GetParentOfType(typeof(ConceptualEntityType)) as ConceptualEntityType;
            var association    = efObject.GetParentOfType(typeof(Association)) as Association;
            var associationSet = efObject as AssociationSet;
            var entitySet      = efObject as EntitySet;

            // if efobject is an associationset, check if the corresponding association is in the diagram.
            if (associationSet != null &&
                associationSet.Association.Status == BindingStatus.Known)
            {
                association = associationSet.Association.Target;
            }

            // if efobject is an entity-set, Return true only if all the entity-types contained in the set are represented in the diagram.
            if (entitySet != null)
            {
                foreach (var et in entitySet.GetEntityTypesInTheSet())
                {
                    if (entityTypesInDiagram.Contains(et) == false)
                    {
                        return(false);
                    }
                }
                return(true);
            }
            else if (entityType != null)
            {
                return(entityTypesInDiagram.Contains(entityType));
            }
            else if (association != null)
            {
                var associationsInDiagram = AssociationConnectors.Select(a => a.Association.Target).ToList();
                return(associationsInDiagram.Contains(association));
            }
            return(false);
        }
Пример #2
0
        // Given an EFObject, this will transform it into something that should be referenceable in the explorer tree.
        internal static EFElement GetNavigationTargetForEFObject(EFObject efObject)
        {
            // find the first parent of EFObject that is an EFElement.  This is what we want to navigate to.
            var efElement = efObject as EFElement;

            if (efElement == null)
            {
                efElement = efObject.GetParentOfType(typeof(EFElement)) as EFElement;
            }
            Debug.Assert(efElement != null, "Unable to find parent EFElement of EFObject");

            var propertyRef          = efElement as PropertyRef;
            var propertyRefContainer = efElement as PropertyRefContainer;

            if (propertyRef != null ||
                propertyRefContainer != null)
            {
                Property target = null;

                if (propertyRef != null)
                {
                    if (propertyRef.Name.Target != null)
                    {
                        target    = propertyRef.Name.Target;
                        efElement = target;
                    }
                }
                else if (propertyRefContainer != null)
                {
                    // use first referenced Property
                    foreach (var pr in propertyRefContainer.PropertyRefs)
                    {
                        if (pr.Name.Target != null)
                        {
                            target    = pr.Name.Target;
                            efElement = target;
                            break;
                        }
                    }
                }

                if (target == null)
                {
                    // Couldn't find a property to reference, so try for a parent EntityType or Association.
                    EFElement rtrn = efElement.GetParentOfType(typeof(EntityType)) as EntityType;
                    if (rtrn == null)
                    {
                        rtrn = efElement.GetParentOfType(typeof(Association)) as Association;
                    }
                    Debug.Assert(
                        rtrn != null, "Couldn't find EntityType or Association when swizzling EFObject of type " + efElement.GetType());
                    efElement = rtrn;
                }
            }
            else if (efElement is AssociationEnd)
            {
                Debug.Assert(
                    efElement.Parent is Association, "Found unexpected parent type of AssociationEnd:  " + efElement.Parent.GetType());
                efElement = efElement.Parent as EFElement;
            }
            else if (efElement is AssociationSetEnd)
            {
                Debug.Assert(
                    efElement.Parent is AssociationSet, "Found unexpected parent type of AssociationSetEnd:  " + efElement.Parent.GetType());
                efElement = efElement.Parent as EFElement;
            }
            else if (efElement is ReferentialConstraint)
            {
                Debug.Assert(
                    efElement.Parent is Association, "Found unexpected parent type of ReferentialConstraint:  " + efElement.Parent.GetType());
                efElement = efElement.Parent as EFElement;
            }

            // some elements are not displayed in the Explorer - if so search for parent that is
            while (null != efElement &&
                   !EntityDesignModelToExplorerModelXRef.IsDisplayedInExplorer(efElement))
            {
                efElement = efElement.Parent as EFElement;
            }
            return(efElement);
        }
        /// <summary>
        ///     This class will set the focus on the "most-appropriate" DSL node for the given EFObject and DSL Diagram.  It is assumed that the
        ///     EFObject is either a C-Space node, or an M-space node.
        /// </summary>
        internal static bool NavigateToDSLNodeInDiagram(EntityDesignerDiagram diagram, EFObject efobject)
        {
            var foundDSLElementMatchInDiagram = false;
            var context = PackageManager.Package.DocumentFrameMgr.EditingContextManager.GetNewOrExistingContext(efobject.Artifact.Uri);

            // find the model parent (if this is a c-space object)
            var cModel = efobject.GetParentOfType(typeof(ConceptualEntityModel)) as ConceptualEntityModel;

            // by default, we assume that this our c-space object
            var      cspaceEFObject = efobject;
            EFObject mspaceEFObject = null;

            if (cModel == null)
            {
                var mModel = efobject.GetParentOfType(typeof(MappingModel)) as MappingModel;
                Debug.Assert(mModel != null, "efobject is neither in c-space or s-space");

                // if this is a mapping node, then we want to find the closest corresponding c-space node
                // to which this mapping node is mapped, and set the focus on that.
                cspaceEFObject = GetCSpaceEFObjectForMSpaceEFObject(efobject);
                mspaceEFObject = efobject;
            }

            // navigate to the shape in the DSL designer
            var diagramItemCollection = new DiagramItemCollection();

            RetrieveDiagramItemCollectionForEFObject(diagram, cspaceEFObject, diagramItemCollection);
            if (diagram != null &&
                diagramItemCollection.Count > 0)
            {
                diagram.Show();

                if (diagram.ActiveDiagramView != null)
                {
                    diagram.ActiveDiagramView.Focus();
                    diagram.ActiveDiagramView.Selection.Set(diagramItemCollection);
                    diagram.EnsureSelectionVisible();
                }
                else
                {
                    // If no active view exists, do the following:
                    // - Set the selection on the first associated views (if any).
                    // - Set InitialSelectionDIagramItemSelectionProperty to prevent the first EntityTypeShape to be selected (default behavior)
                    //   This case can happen when the diagram is not initialized or is not fully rendered.
                    diagram.InitialDiagramItemSelection = diagramItemCollection;
                    if (diagram.ClientViews != null &&
                        diagram.ClientViews.Count > 0)
                    {
                        foreach (DiagramClientView clientView in diagram.ClientViews)
                        {
                            clientView.Selection.Set(diagramItemCollection);
                            clientView.Selection.EnsureVisible(DiagramClientView.EnsureVisiblePreferences.ScrollIntoViewCenter);
                            break;
                        }
                    }
                }
                foundDSLElementMatchInDiagram = true;
            }

            if (mspaceEFObject != null) // navigate to the item in the mapping screen (if we are doing MSL items)
            {
                var mappingDetailsInfo = context.Items.GetValue <MappingDetailsInfo>();
                if (mappingDetailsInfo.MappingDetailsWindow != null)
                {
                    mappingDetailsInfo.MappingDetailsWindow.NavigateTo(mspaceEFObject);
                }
            }

            return(foundDSLElementMatchInDiagram);
        }
        private static void RetrieveDiagramItemCollectionForEFObject(
            EntityDesignerDiagram diagram, EFObject efobject, DiagramItemCollection diagramItemCollection)
        {
            if (efobject == null)
            {
                return;
            }

            var cModel = efobject.RuntimeModelRoot() as ConceptualEntityModel;

            if (cModel == null)
            {
                // this either isn't a c-space object, or it is the ConceptualEntityModel node, so just return null
                return;
            }

            // if this is a child element of the association, return the diagram item for the association
            if (!(efobject is Association))
            {
                var association = efobject.GetParentOfType(typeof(Association)) as Association;
                if (association != null)
                {
                    RetrieveDiagramItemCollectionForEFObject(diagram, association, diagramItemCollection);
                    return;
                }
            }

            if (efobject is Association)
            {
                var shapeElement = GetDesignerShapeElementForEFObject(diagram, efobject);
                if (shapeElement != null)
                {
                    diagramItemCollection.Add(new DiagramItem(shapeElement));
                    return;
                }
            }
            else if (efobject is NavigationProperty)
            {
                var np              = efobject as NavigationProperty;
                var shapeElement    = GetDesignerShapeElementForEFObject(diagram, np.Parent);
                var entityTypeShape = shapeElement as EntityTypeShape;

                if (entityTypeShape != null)
                {
                    // get the view model navigation property
                    var vmNavProp = diagram.ModelElement.ModelXRef.GetExisting(np) as ViewModel.NavigationProperty;

                    // try to create the DiagramItem from this
                    if (vmNavProp != null)
                    {
                        var index = entityTypeShape.NavigationCompartment.Items.IndexOf(vmNavProp);
                        if (index >= 0)
                        {
                            diagramItemCollection.Add(
                                new DiagramItem(
                                    entityTypeShape.NavigationCompartment, entityTypeShape.NavigationCompartment.ListField,
                                    new ListItemSubField(index)));
                            return;
                        }
                    }
                }
            }
            else if (efobject is Property)
            {
                var prop = efobject as Property;
                if (prop.IsComplexTypeProperty)
                {
                    // complex type properties are not supported in the designer
                    return;
                }
                var shapeElement    = GetDesignerShapeElementForEFObject(diagram, prop.Parent);
                var entityTypeShape = shapeElement as EntityTypeShape;
                if (entityTypeShape != null)
                {
                    // get the view model  property
                    var vmProp = diagram.ModelElement.ModelXRef.GetExisting(prop) as ViewModel.Property;

                    if (vmProp != null)
                    {
                        var index = entityTypeShape.PropertiesCompartment.Items.IndexOf(vmProp);
                        if (index >= 0)
                        {
                            diagramItemCollection.Add(
                                new DiagramItem(
                                    entityTypeShape.PropertiesCompartment, entityTypeShape.PropertiesCompartment.ListField,
                                    new ListItemSubField(index)));
                            return;
                        }
                    }
                }
            }
            else if (efobject is EntityType)
            {
                var shapeElement = GetDesignerShapeElementForEFObject(diagram, efobject);
                if (shapeElement != null)
                {
                    diagramItemCollection.Add(new DiagramItem(shapeElement));
                    return;
                }
            }
            else if (efobject is EntitySet)
            {
                var es = efobject as EntitySet;
                foreach (var entityType in es.GetEntityTypesInTheSet())
                {
                    if (entityType != null)
                    {
                        RetrieveDiagramItemCollectionForEFObject(diagram, entityType, diagramItemCollection);
                    }
                }
                return;
            }
            else if (efobject is AssociationSet)
            {
                // return a diagram item for the association
                var associationSet = efobject as AssociationSet;
                var association    = associationSet.Association.Target;
                if (association != null)
                {
                    RetrieveDiagramItemCollectionForEFObject(diagram, association, diagramItemCollection);
                    return;
                }
            }
            else if (efobject is AssociationSetEnd)
            {
                var associationSetEnd = efobject as AssociationSetEnd;
                var end = associationSetEnd.Role.Target;
                if (end != null)
                {
                    RetrieveDiagramItemCollectionForEFObject(diagram, end, diagramItemCollection);
                    return;
                }
                else
                {
                    var es = associationSetEnd.EntitySet.Target;
                    if (es != null)
                    {
                        RetrieveDiagramItemCollectionForEFObject(diagram, es, diagramItemCollection);
                        return;
                    }
                }
            }
            else if (efobject is PropertyRef)
            {
                var pref = efobject as PropertyRef;
                if (pref.Name.Target != null)
                {
                    RetrieveDiagramItemCollectionForEFObject(diagram, pref.Name.Target, diagramItemCollection);
                    return;
                }
            }
            else if (efobject is PropertyRefContainer)
            {
                var prefContainer = efobject as PropertyRefContainer;

                // just use the first entry in the list.
                foreach (var pref in prefContainer.PropertyRefs)
                {
                    RetrieveDiagramItemCollectionForEFObject(diagram, pref, diagramItemCollection);
                    return;
                }
            }
            else if (efobject is EFAttribute)
            {
                // this is an EFAttribute node, so get the DiagramItem for the parent
                RetrieveDiagramItemCollectionForEFObject(diagram, efobject.Parent, diagramItemCollection);
                return;
            }
            else if (efobject is ConceptualEntityModel)
            {
                // nothing in the DSL surface to map to, so return null
                return;
            }
            else if (efobject is ConceptualEntityContainer)
            {
                // nothing in the DSL surface to map to, so return null
                return;
            }
            else if (efobject is FunctionImport)
            {
                // nothing in the DSL surface to map to, so return null
                return;
            }
            else
            {
                Debug.Fail("unexpected type of efobject.  type = " + efobject.GetType());
                if (efobject.Parent != null)
                {
                    RetrieveDiagramItemCollectionForEFObject(diagram, efobject.Parent, diagramItemCollection);
                }
            }
        }
        /// <summary>
        ///     Given a efobject in m-space (ie, it is defined in the mapping section of the edmx file), find the
        ///     closest object in the c-space (ie, defined in the conceptual schema).  We do this by looking
        ///     for binding objects of the current node bound to something in c-space. If there is no such object, we
        ///     recursively call this on efobject's parent.
        /// </summary>
        /// <param name="efobject"></param>
        /// <returns></returns>
        private static EFObject GetCSpaceEFObjectForMSpaceEFObject(EFObject mspaceEFObject)
        {
            EFObject cspaceEFObject = null;
            var      o = mspaceEFObject;

            // see if this m-space object has a parent of an association set mapping.
            var asm = mspaceEFObject.GetParentOfType(typeof(AssociationSetMapping)) as AssociationSetMapping;

            if (asm != null)
            {
                var associationSet = asm.Name.Target;
                if (associationSet != null)
                {
                    var association = associationSet.Association.Target;
                    if (association != null)
                    {
                        Debug.Assert(
                            association.RuntimeModelRoot() is ConceptualEntityModel, "Expected association to be in C-space, but it is not!");
                        return(association);
                    }
                }
            }

            // see if this is a node that requires the function view in the mapping pane
            var mfm                = mspaceEFObject.GetParentOfType(typeof(ModificationFunctionMapping)) as ModificationFunctionMapping;
            var context            = PackageManager.Package.DocumentFrameMgr.EditingContextManager.GetNewOrExistingContext(mspaceEFObject.Artifact.Uri);
            var mappingDetailsInfo = context.Items.GetValue <MappingDetailsInfo>();

            if (mfm != null)
            {
                mappingDetailsInfo.EntityMappingMode = EntityMappingModes.Functions;
            }
            else
            {
                mappingDetailsInfo.EntityMappingMode = EntityMappingModes.Tables;
            }

            // default case, walk up the model looking for node that has a binding bound to something in c-space.
            while (cspaceEFObject == null &&
                   o != null)
            {
                var binding   = o as ItemBinding;
                var container = o as EFContainer;

                if (binding != null)
                {
                    // see if this binding is bound to something in c-space
                    cspaceEFObject = GetCSpaceObjectFromBinding(binding);
                }
                else if (container != null)
                {
                    // see if any direct children are bindings bound to something in c-space
                    foreach (var child in container.Children)
                    {
                        // check every binding to see if it is bound to seomthing in cspace
                        var b = child as ItemBinding;
                        if (b != null)
                        {
                            cspaceEFObject = GetCSpaceObjectFromBinding(b);
                            if (cspaceEFObject != null)
                            {
                                // break out of the for loop
                                break;
                            }
                        }
                    }
                }

                if (cspaceEFObject == null)
                {
                    o = o.Parent;
                }
            }
            return(cspaceEFObject);
        }
        // Given an EFObject, this will transform it into something that should be referenceable in the explorer tree.
        internal static EFElement GetNavigationTargetForEFObject(EFObject efObject)
        {
            // find the first parent of EFObject that is an EFElement.  This is what we want to navigate to.
            var efElement = efObject as EFElement;
            if (efElement == null)
            {
                efElement = efObject.GetParentOfType(typeof(EFElement)) as EFElement;
            }
            Debug.Assert(efElement != null, "Unable to find parent EFElement of EFObject");

            var propertyRef = efElement as PropertyRef;
            var propertyRefContainer = efElement as PropertyRefContainer;
            if (propertyRef != null
                || propertyRefContainer != null)
            {
                Property target = null;

                if (propertyRef != null)
                {
                    if (propertyRef.Name.Target != null)
                    {
                        target = propertyRef.Name.Target;
                        efElement = target;
                    }
                }
                else if (propertyRefContainer != null)
                {
                    // use first referenced Property
                    foreach (var pr in propertyRefContainer.PropertyRefs)
                    {
                        if (pr.Name.Target != null)
                        {
                            target = pr.Name.Target;
                            efElement = target;
                            break;
                        }
                    }
                }

                if (target == null)
                {
                    // Couldn't find a property to reference, so try for a parent EntityType or Association. 
                    EFElement rtrn = efElement.GetParentOfType(typeof(EntityType)) as EntityType;
                    if (rtrn == null)
                    {
                        rtrn = efElement.GetParentOfType(typeof(Association)) as Association;
                    }
                    Debug.Assert(
                        rtrn != null, "Couldn't find EntityType or Association when swizzling EFObject of type " + efElement.GetType());
                    efElement = rtrn;
                }
            }
            else if (efElement is AssociationEnd)
            {
                Debug.Assert(
                    efElement.Parent is Association, "Found unexpected parent type of AssociationEnd:  " + efElement.Parent.GetType());
                efElement = efElement.Parent as EFElement;
            }
            else if (efElement is AssociationSetEnd)
            {
                Debug.Assert(
                    efElement.Parent is AssociationSet, "Found unexpected parent type of AssociationSetEnd:  " + efElement.Parent.GetType());
                efElement = efElement.Parent as EFElement;
            }
            else if (efElement is ReferentialConstraint)
            {
                Debug.Assert(
                    efElement.Parent is Association, "Found unexpected parent type of ReferentialConstraint:  " + efElement.Parent.GetType());
                efElement = efElement.Parent as EFElement;
            }

            // some elements are not displayed in the Explorer - if so search for parent that is
            while (null != efElement
                   && !EntityDesignModelToExplorerModelXRef.IsDisplayedInExplorer(efElement))
            {
                efElement = efElement.Parent as EFElement;
            }
            return efElement;
        }
        /// <summary>
        ///     This class will set the focus on the "most-appropriate" DSL node for the given EFObject and DSL Diagram.  It is assumed that the
        ///     EFObject is either a C-Space node, or an M-space node.
        /// </summary>
        internal static bool NavigateToDSLNodeInDiagram(EntityDesignerDiagram diagram, EFObject efobject)
        {
            var foundDSLElementMatchInDiagram = false;
            var context = PackageManager.Package.DocumentFrameMgr.EditingContextManager.GetNewOrExistingContext(efobject.Artifact.Uri);

            // find the model parent (if this is a c-space object)
            var cModel = efobject.GetParentOfType(typeof(ConceptualEntityModel)) as ConceptualEntityModel;

            // by default, we assume that this our c-space object
            var cspaceEFObject = efobject;
            EFObject mspaceEFObject = null;
            if (cModel == null)
            {
                var mModel = efobject.GetParentOfType(typeof(MappingModel)) as MappingModel;
                Debug.Assert(mModel != null, "efobject is neither in c-space or s-space");

                // if this is a mapping node, then we want to find the closest corresponding c-space node
                // to which this mapping node is mapped, and set the focus on that.
                cspaceEFObject = GetCSpaceEFObjectForMSpaceEFObject(efobject);
                mspaceEFObject = efobject;
            }

            // navigate to the shape in the DSL designer
            var diagramItemCollection = new DiagramItemCollection();
            RetrieveDiagramItemCollectionForEFObject(diagram, cspaceEFObject, diagramItemCollection);
            if (diagram != null
                && diagramItemCollection.Count > 0)
            {
                diagram.Show();

                if (diagram.ActiveDiagramView != null)
                {
                    diagram.ActiveDiagramView.Focus();
                    diagram.ActiveDiagramView.Selection.Set(diagramItemCollection);
                    diagram.EnsureSelectionVisible();
                }
                else
                {
                    // If no active view exists, do the following:
                    // - Set the selection on the first associated views (if any).
                    // - Set InitialSelectionDIagramItemSelectionProperty to prevent the first EntityTypeShape to be selected (default behavior)
                    //   This case can happen when the diagram is not initialized or is not fully rendered.
                    diagram.InitialDiagramItemSelection = diagramItemCollection;
                    if (diagram.ClientViews != null
                        && diagram.ClientViews.Count > 0)
                    {
                        foreach (DiagramClientView clientView in diagram.ClientViews)
                        {
                            clientView.Selection.Set(diagramItemCollection);
                            clientView.Selection.EnsureVisible(DiagramClientView.EnsureVisiblePreferences.ScrollIntoViewCenter);
                            break;
                        }
                    }
                }
                foundDSLElementMatchInDiagram = true;
            }

            if (mspaceEFObject != null) // navigate to the item in the mapping screen (if we are doing MSL items)
            {
                var mappingDetailsInfo = context.Items.GetValue<MappingDetailsInfo>();
                if (mappingDetailsInfo.MappingDetailsWindow != null)
                {
                    mappingDetailsInfo.MappingDetailsWindow.NavigateTo(mspaceEFObject);
                }
            }

            return foundDSLElementMatchInDiagram;
        }
        private static void RetrieveDiagramItemCollectionForEFObject(
            EntityDesignerDiagram diagram, EFObject efobject, DiagramItemCollection diagramItemCollection)
        {
            if (efobject == null)
            {
                return;
            }

            var cModel = efobject.RuntimeModelRoot() as ConceptualEntityModel;

            if (cModel == null)
            {
                // this either isn't a c-space object, or it is the ConceptualEntityModel node, so just return null
                return;
            }

            // if this is a child element of the association, return the diagram item for the association
            if (!(efobject is Association))
            {
                var association = efobject.GetParentOfType(typeof(Association)) as Association;
                if (association != null)
                {
                    RetrieveDiagramItemCollectionForEFObject(diagram, association, diagramItemCollection);
                    return;
                }
            }

            if (efobject is Association)
            {
                var shapeElement = GetDesignerShapeElementForEFObject(diagram, efobject);
                if (shapeElement != null)
                {
                    diagramItemCollection.Add(new DiagramItem(shapeElement));
                    return;
                }
            }
            else if (efobject is NavigationProperty)
            {
                var np = efobject as NavigationProperty;
                var shapeElement = GetDesignerShapeElementForEFObject(diagram, np.Parent);
                var entityTypeShape = shapeElement as EntityTypeShape;

                if (entityTypeShape != null)
                {
                    // get the view model navigation property
                    var vmNavProp = diagram.ModelElement.ModelXRef.GetExisting(np) as ViewModel.NavigationProperty;

                    // try to create the DiagramItem from this
                    if (vmNavProp != null)
                    {
                        var index = entityTypeShape.NavigationCompartment.Items.IndexOf(vmNavProp);
                        if (index >= 0)
                        {
                            diagramItemCollection.Add(
                                new DiagramItem(
                                    entityTypeShape.NavigationCompartment, entityTypeShape.NavigationCompartment.ListField,
                                    new ListItemSubField(index)));
                            return;
                        }
                    }
                }
            }
            else if (efobject is Property)
            {
                var prop = efobject as Property;
                if (prop.IsComplexTypeProperty)
                {
                    // complex type properties are not supported in the designer
                    return;
                }
                var shapeElement = GetDesignerShapeElementForEFObject(diagram, prop.Parent);
                var entityTypeShape = shapeElement as EntityTypeShape;
                if (entityTypeShape != null)
                {
                    // get the view model  property
                    var vmProp = diagram.ModelElement.ModelXRef.GetExisting(prop) as ViewModel.Property;

                    if (vmProp != null)
                    {
                        var index = entityTypeShape.PropertiesCompartment.Items.IndexOf(vmProp);
                        if (index >= 0)
                        {
                            diagramItemCollection.Add(
                                new DiagramItem(
                                    entityTypeShape.PropertiesCompartment, entityTypeShape.PropertiesCompartment.ListField,
                                    new ListItemSubField(index)));
                            return;
                        }
                    }
                }
            }
            else if (efobject is EntityType)
            {
                var shapeElement = GetDesignerShapeElementForEFObject(diagram, efobject);
                if (shapeElement != null)
                {
                    diagramItemCollection.Add(new DiagramItem(shapeElement));
                    return;
                }
            }
            else if (efobject is EntitySet)
            {
                var es = efobject as EntitySet;
                foreach (var entityType in es.GetEntityTypesInTheSet())
                {
                    if (entityType != null)
                    {
                        RetrieveDiagramItemCollectionForEFObject(diagram, entityType, diagramItemCollection);
                    }
                }
                return;
            }
            else if (efobject is AssociationSet)
            {
                // return a diagram item for the association
                var associationSet = efobject as AssociationSet;
                var association = associationSet.Association.Target;
                if (association != null)
                {
                    RetrieveDiagramItemCollectionForEFObject(diagram, association, diagramItemCollection);
                    return;
                }
            }
            else if (efobject is AssociationSetEnd)
            {
                var associationSetEnd = efobject as AssociationSetEnd;
                var end = associationSetEnd.Role.Target;
                if (end != null)
                {
                    RetrieveDiagramItemCollectionForEFObject(diagram, end, diagramItemCollection);
                    return;
                }
                else
                {
                    var es = associationSetEnd.EntitySet.Target;
                    if (es != null)
                    {
                        RetrieveDiagramItemCollectionForEFObject(diagram, es, diagramItemCollection);
                        return;
                    }
                }
            }
            else if (efobject is PropertyRef)
            {
                var pref = efobject as PropertyRef;
                if (pref.Name.Target != null)
                {
                    RetrieveDiagramItemCollectionForEFObject(diagram, pref.Name.Target, diagramItemCollection);
                    return;
                }
            }
            else if (efobject is PropertyRefContainer)
            {
                var prefContainer = efobject as PropertyRefContainer;

                // just use the first entry in the list.
                foreach (var pref in prefContainer.PropertyRefs)
                {
                    RetrieveDiagramItemCollectionForEFObject(diagram, pref, diagramItemCollection);
                    return;
                }
            }
            else if (efobject is EFAttribute)
            {
                // this is an EFAttribute node, so get the DiagramItem for the parent
                RetrieveDiagramItemCollectionForEFObject(diagram, efobject.Parent, diagramItemCollection);
                return;
            }
            else if (efobject is ConceptualEntityModel)
            {
                // nothing in the DSL surface to map to, so return null
                return;
            }
            else if (efobject is ConceptualEntityContainer)
            {
                // nothing in the DSL surface to map to, so return null
                return;
            }
            else if (efobject is FunctionImport)
            {
                // nothing in the DSL surface to map to, so return null
                return;
            }
            else
            {
                Debug.Fail("unexpected type of efobject.  type = " + efobject.GetType());
                if (efobject.Parent != null)
                {
                    RetrieveDiagramItemCollectionForEFObject(diagram, efobject.Parent, diagramItemCollection);
                }
            }
        }
        /// <summary>
        ///     Given a efobject in m-space (ie, it is defined in the mapping section of the edmx file), find the
        ///     closest object in the c-space (ie, defined in the conceptual schema).  We do this by looking
        ///     for binding objects of the current node bound to something in c-space. If there is no such object, we
        ///     recursively call this on efobject's parent.
        /// </summary>
        /// <param name="efobject"></param>
        /// <returns></returns>
        private static EFObject GetCSpaceEFObjectForMSpaceEFObject(EFObject mspaceEFObject)
        {
            EFObject cspaceEFObject = null;
            var o = mspaceEFObject;

            // see if this m-space object has a parent of an association set mapping.
            var asm = mspaceEFObject.GetParentOfType(typeof(AssociationSetMapping)) as AssociationSetMapping;
            if (asm != null)
            {
                var associationSet = asm.Name.Target;
                if (associationSet != null)
                {
                    var association = associationSet.Association.Target;
                    if (association != null)
                    {
                        Debug.Assert(
                            association.RuntimeModelRoot() is ConceptualEntityModel, "Expected association to be in C-space, but it is not!");
                        return association;
                    }
                }
            }

            // see if this is a node that requires the function view in the mapping pane
            var mfm = mspaceEFObject.GetParentOfType(typeof(ModificationFunctionMapping)) as ModificationFunctionMapping;
            var context = PackageManager.Package.DocumentFrameMgr.EditingContextManager.GetNewOrExistingContext(mspaceEFObject.Artifact.Uri);
            var mappingDetailsInfo = context.Items.GetValue<MappingDetailsInfo>();
            if (mfm != null)
            {
                mappingDetailsInfo.EntityMappingMode = EntityMappingModes.Functions;
            }
            else
            {
                mappingDetailsInfo.EntityMappingMode = EntityMappingModes.Tables;
            }

            // default case, walk up the model looking for node that has a binding bound to something in c-space.  
            while (cspaceEFObject == null
                   && o != null)
            {
                var binding = o as ItemBinding;
                var container = o as EFContainer;

                if (binding != null)
                {
                    // see if this binding is bound to something in c-space
                    cspaceEFObject = GetCSpaceObjectFromBinding(binding);
                }
                else if (container != null)
                {
                    // see if any direct children are bindings bound to something in c-space
                    foreach (var child in container.Children)
                    {
                        // check every binding to see if it is bound to seomthing in cspace
                        var b = child as ItemBinding;
                        if (b != null)
                        {
                            cspaceEFObject = GetCSpaceObjectFromBinding(b);
                            if (cspaceEFObject != null)
                            {
                                // break out of the for loop
                                break;
                            }
                        }
                    }
                }

                if (cspaceEFObject == null)
                {
                    o = o.Parent;
                }
            }
            return cspaceEFObject;
        }