示例#1
0
        internal AssociationIdentity GetAssociationIdentity(Association a)
        {
            AssociationIdentity id = null;

            _associationToAssociationIdentity.TryGetValue(a, out id);
            return(id);
        }
示例#2
0
        internal static AssociationSummary ConstructAssociationSummary(EFArtifact artifact)
        {
            var ecm = artifact.MappingModel().FirstEntityContainerMapping;

            var summary = new AssociationSummary();

            if (!EdmFeatureManager.GetForeignKeysInModelFeatureState(artifact.SchemaVersion).IsEnabled())
            {
                if (ecm != null)
                {
                    // Foreign keys in the model are not supported for this EDMX version.
                    foreach (var asm in ecm.AssociationSetMappings())
                    {
                        var cSideAssociation = asm.TypeName.Target;

                        if (null != cSideAssociation)
                        {
                            var assocId = AssociationIdentityForAssociationSetMapping.CreateAssociationIdentity(asm);
                            if (null != assocId)
                            {
                                summary.Add(cSideAssociation, assocId);
                            }
                        }
                    }
                }
            }
            else
            {
                // Foreign keys in the model are supported for this EDMX version.
                foreach (var a in artifact.ConceptualModel().Associations())
                {
                    AssociationIdentity assocId = null;
                    if (a.IsManyToMany == false &&
                        a.ReferentialConstraint != null)
                    {
                        assocId = AssociationIdentityForReferentialConstraint.CreateAssociationIdentity(a.ReferentialConstraint);
                    }
                    else
                    {
                        var asm = ModelHelper.FindAssociationSetMappingForConceptualAssociation(a);
                        if (asm != null)
                        {
                            assocId = AssociationIdentityForAssociationSetMapping.CreateAssociationIdentity(asm);
                        }
                    }
                    if (null != assocId)
                    {
                        summary.Add(a, assocId);
                    }
                }
            }
            return(summary);
        }
 internal void Add(Association a, AssociationIdentity aID)
 {
     _associationToAssociationIdentity.Add(a, aID);
     foreach (var table in aID.AssociationTables)
     {
         List<AssociationIdentity> l = null;
         if (false == _dependentEndTablesToAssociationIdentities.TryGetValue(table, out l))
         {
             l = new List<AssociationIdentity>();
             _dependentEndTablesToAssociationIdentities.Add(table, l);
         }
         l.Add(aID);
     }
 }
示例#4
0
 internal void Add(Association a, AssociationIdentity aID)
 {
     _associationToAssociationIdentity.Add(a, aID);
     foreach (var table in aID.AssociationTables)
     {
         List <AssociationIdentity> l = null;
         if (false == _dependentEndTablesToAssociationIdentities.TryGetValue(table, out l))
         {
             l = new List <AssociationIdentity>();
             _dependentEndTablesToAssociationIdentities.Add(table, l);
         }
         l.Add(aID);
     }
 }
 internal bool Contains(AssociationIdentity id)
 {
     // Since we can’t compare an association with an RC to an association with an ASM for equality, we can’t use a HashSet<AssociationIdentity>
     // to do the “contains” lookup.  So, we use the dependent end tables to narrow down the search, and then scan each 
     // candidate AssociationIdentity to see if it covers the passed in id.
     foreach (var table in id.AssociationTables)
     {
         List<AssociationIdentity> otherIDs = null;
         if (_dependentEndTablesToAssociationIdentities.TryGetValue(table, out otherIDs))
         {
             foreach (var otherID in otherIDs)
             {
                 if (id.IsCoveredBy(otherID))
                 {
                     return true;
                 }
             }
         }
     }
     return false;
 }
示例#6
0
 internal bool Contains(AssociationIdentity id)
 {
     // Since we can’t compare an association with an RC to an association with an ASM for equality, we can’t use a HashSet<AssociationIdentity>
     // to do the “contains” lookup.  So, we use the dependent end tables to narrow down the search, and then scan each
     // candidate AssociationIdentity to see if it covers the passed in id.
     foreach (var table in id.AssociationTables)
     {
         List <AssociationIdentity> otherIDs = null;
         if (_dependentEndTablesToAssociationIdentities.TryGetValue(table, out otherIDs))
         {
             foreach (var otherID in otherIDs)
             {
                 if (id.IsCoveredBy(otherID))
                 {
                     return(true);
                 }
             }
         }
     }
     return(false);
 }
示例#7
0
        internal bool IsCoveredBy(AssociationIdentity id2)
        {
            var id1 = this;

            if (id1 is AssociationIdentityForAssociationSetMapping &&
                id2 is AssociationIdentityForAssociationSetMapping)
            {
                var id1AsAIFASM = id1 as AssociationIdentityForAssociationSetMapping;
                var id2AsAIFASM = id2 as AssociationIdentityForAssociationSetMapping;
                return(id1AsAIFASM.IsCoveredBy(id2AsAIFASM));
            }
            else if (id1 is AssociationIdentityForReferentialConstraint &&
                     id2 is AssociationIdentityForReferentialConstraint)
            {
                var id1AsAIFRC = id1 as AssociationIdentityForReferentialConstraint;
                var id2AsAIFRC = id2 as AssociationIdentityForReferentialConstraint;
                return(id1AsAIFRC.IsCoveredBy(id2AsAIFRC));
            }
            else if (id1 is AssociationIdentityForAssociationSetMapping &&
                     id2 is AssociationIdentityForReferentialConstraint)
            {
                var rcid  = id2 as AssociationIdentityForReferentialConstraint;
                var asmid = id1 as AssociationIdentityForAssociationSetMapping;
                return(IsCoveredBy(rcid, asmid));
            }
            else if (id1 is AssociationIdentityForReferentialConstraint &&
                     id2 is AssociationIdentityForAssociationSetMapping)
            {
                var rcid  = id1 as AssociationIdentityForReferentialConstraint;
                var asmid = id2 as AssociationIdentityForAssociationSetMapping;
                return(IsCoveredBy(rcid, asmid));
            }
            else
            {
                Debug.Fail("unexpected type of AssociationIdentity found id1=" + id1.TraceString() + ", id2=" + id2.TraceString());
            }

            return(false);
        }
        internal bool IsCoveredBy(AssociationIdentity id2)
        {
            var id1 = this;
            if (id1 is AssociationIdentityForAssociationSetMapping
                && id2 is AssociationIdentityForAssociationSetMapping)
            {
                var id1AsAIFASM = id1 as AssociationIdentityForAssociationSetMapping;
                var id2AsAIFASM = id2 as AssociationIdentityForAssociationSetMapping;
                return id1AsAIFASM.IsCoveredBy(id2AsAIFASM);
            }
            else if (id1 is AssociationIdentityForReferentialConstraint
                     && id2 is AssociationIdentityForReferentialConstraint)
            {
                var id1AsAIFRC = id1 as AssociationIdentityForReferentialConstraint;
                var id2AsAIFRC = id2 as AssociationIdentityForReferentialConstraint;
                return id1AsAIFRC.IsCoveredBy(id2AsAIFRC);
            }
            else if (id1 is AssociationIdentityForAssociationSetMapping
                     && id2 is AssociationIdentityForReferentialConstraint)
            {
                var rcid = id2 as AssociationIdentityForReferentialConstraint;
                var asmid = id1 as AssociationIdentityForAssociationSetMapping;
                return IsCoveredBy(rcid, asmid);
            }
            else if (id1 is AssociationIdentityForReferentialConstraint
                     && id2 is AssociationIdentityForAssociationSetMapping)
            {
                var rcid = id1 as AssociationIdentityForReferentialConstraint;
                var asmid = id2 as AssociationIdentityForAssociationSetMapping;
                return IsCoveredBy(rcid, asmid);
            }
            else
            {
                Debug.Fail("unexpected type of AssociationIdentity found id1=" + id1.TraceString() + ", id2=" + id2.TraceString());
            }

            return false;
        }
        private bool HasBeenReplacedByInheritanceOrSplitEntity(
            Association assoc, AssociationIdentity assocId,
            Dictionary<EntityType, EntityType> tempArtifactCEntityTypeToNewCEntityTypeInExistingArtifact)
        {
            if (2 != assoc.AssociationEnds().Count)
            {
                Debug.Fail(
                    "Received incorrect number of AssociationEnds (" + assoc.AssociationEnds().Count + ") for Association "
                    + assoc.ToPrettyString() + " should be 2.");
                return false;
            }

            // check 1:1 or 1:0..1
            var assocEnds = assoc.AssociationEnds();
            var assocEnd1 = assocEnds[0];
            var assocEnd2 = assocEnds[1];
            if (!(ModelConstants.Multiplicity_One == assocEnd1.Multiplicity.Value
                  && (ModelConstants.Multiplicity_One == assocEnd2.Multiplicity.Value ||
                      ModelConstants.Multiplicity_ZeroOrOne == assocEnd2.Multiplicity.Value))
                ||
                (ModelConstants.Multiplicity_One == assocEnd2.Multiplicity.Value
                 && (ModelConstants.Multiplicity_One == assocEnd1.Multiplicity.Value ||
                     ModelConstants.Multiplicity_ZeroOrOne == assocEnd1.Multiplicity.Value)))
            {
                return false;
            }

            // get C-side EntityTypes for each AssociationEnd
            var et1 = assocEnd1.Type.Target as ConceptualEntityType;
            var et2 = assocEnd2.Type.Target as ConceptualEntityType;
            if (null == et1)
            {
                Debug.Fail("EntityType et1 is not a ConceptualEntityType");
                return false;
            }
            else if (null == et2)
            {
                Debug.Fail("EntityType et2 is not a ConceptualEntityType");
                return false;
            }

            // check not both pointing to same entity type (i.e. self-association)
            if (et1.Equals(et2))
            {
                return false;
            }

            // check inheritance relationship

            // First identify the association table and which end 
            // contains that table
            var et1Id = _modelRepresentingDatabase.GetEntityTypeIdentityForEntityType(et1);
            var et2Id = _modelRepresentingDatabase.GetEntityTypeIdentityForEntityType(et2);
            if (null == et1Id)
            {
                Debug.Fail("Could not find EntityTypeIdentity for et1 " + et1.ToPrettyString());
                return false;
            }
            else if (null == et2Id)
            {
                Debug.Fail("Could not find EntityTypeIdentity for et2 " + et2.ToPrettyString());
                return false;
            }

            EntityTypeIdentity etIdNotContainingAssocTable = null;

            var tables = assocId.AssociationTables.GetEnumerator();
            tables.MoveNext();
            var assocTable = tables.Current;

            if (tables.MoveNext())
            {
                //
                // If we get here, the properties involved in a Ref Constraint were mapped to multiple tables.  This implies inheritance 
                // or horizontal partitioning on the database (ie, the dependent end of the RC is an entity mapped to more than one table, 
                // so the RC spans tables).  
                //
                // We don't ever expect this to be the case for a model generated from model-gen APIs, so assert.  
                //
                Debug.Fail(
                    "An association is mapped to more than one table on the dependent via a referential constraint.  We didn't expect this to happen for a model generated from model gen APIs");
                // just return false here.  It should be OK for us to include this association, and the user can make the call on what to do.
                return false;
            }

            if (et1Id.ContainsDatabaseObject(assocTable))
            {
                etIdNotContainingAssocTable = et2Id;
            }
            else if (et2Id.ContainsDatabaseObject(assocTable))
            {
                etIdNotContainingAssocTable = et1Id;
            }
            else
            {
                // Neither end of a 1:1 or 1:0..1 Association contains the association table.
                // This is an error.
                Debug.Fail(
                    "Neither end of the Association " + assoc.ToPrettyString() + " contains the association table " + assocTable.ToString());
                return false;
            }

            // now find the C-side EntityTypes in the existing artifact
            // for that association table
            var existingEntityTypesForAssocTable =
                _preExistingModel.GetConceptualEntityTypesForDatabaseObject(assocTable);

            // now if any of these EntityTypes has an ancestor which maps 
            // to any of the tables/views in the EntityTypeIdentity of 
            // the _other_ AssociationEnd then we have found the inheritance
            // relationship which replaced this Association
            // Note: this covers the case where one or the other end is a new table/view:
            // if assocTable is "new" then existingEntityTypesForAssocTable will be null,
            // if the other end of the association is "new" then no existing EntityType
            // will have an ancestor type that maps to the tables/views in the other end.
            if (null != existingEntityTypesForAssocTable)
            {
                foreach (var cet in existingEntityTypesForAssocTable)
                {
                    foreach (var tableOrView in etIdNotContainingAssocTable.TablesAndViews)
                    {
                        if (_preExistingModel.HasAncestorTypeThatMapsToDbObject(cet, tableOrView))
                        {
                            return true;
                        }
                    }
                }
            }

            // check split-entity

            // find the C-Side EntityTypes in the existing artifact for both ends
            var existingEntityType1 = FindMatchingConceptualEntityTypeInExistingArtifact(
                et1,
                tempArtifactCEntityTypeToNewCEntityTypeInExistingArtifact);
            var existingEntityType2 = FindMatchingConceptualEntityTypeInExistingArtifact(
                et2,
                tempArtifactCEntityTypeToNewCEntityTypeInExistingArtifact);

            // if either there are no matching EntityTypes or the 2 matching EntityTypes
            // are different in the existing artifact then this is not split-entity
            if (null == existingEntityType1
                || null == existingEntityType2
                || !existingEntityType1.Equals(existingEntityType2))
            {
                return false;
            }

            // check referential constraint
            var refConstraint = assoc.ReferentialConstraint;
            if (null == refConstraint)
            {
                return false;
            }

            return (HasIdenticalKeyToEntityType(refConstraint.Principal)
                    && HasIdenticalKeyToEntityType(refConstraint.Dependent));
        }