/// <summary> /// See whether the AssociationIdentityForAssociationSetMapping other contains a "covering" for this /// i.e. check that the two AssociationIdentityForAssociationSetMapping objects have the same /// AssociationTable and that all AssociationEndIdentity's in this.Ends are covered by /// AssociationEndIdentity's in other.Ends (for definition of "covering" see /// method AssociationEndIdentity.IsCoveredBy(AssociationEndIdentity)) /// </summary> internal bool IsCoveredBy(AssociationIdentityForAssociationSetMapping other) { if (false == AssociationTable.Equals(other.AssociationTable)) { return(false); } foreach (var thisEndId in Ends) { var foundCoveringEndId = false; foreach (var otherEndId in other.Ends) { // check whether thisEndId is covered by otherEndId if (thisEndId.IsCoveredBy(otherEndId)) { // have found an AssociationEndIdentity in other.Ends which covers thisEndId foundCoveringEndId = true; break; } } if (false == foundCoveringEndId) { // no covering AssociationEndIdentity was found for thisEndId in other.Ends return(false); } } // all AssociationEndIdentity's in this.Ends were covered by an AssociationEndIdentity in other.Ends return(true); }
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); }
/// <summary> /// returns true if the AssociationSetMapping is covered by the referential constraint. /// "covers" means that the /// 1. The columns mapped to the RC's principal keys match the columns mapped to the /// association's principal keys. /// 2. For each "pair" of properties that match between the RC & the ASM, the /// ASM's mapped column is contained in the dependent columns of the RC. /// </summary> private static bool IsCoveredBy(AssociationIdentityForReferentialConstraint assRC, AssociationIdentityForAssociationSetMapping asmid) { // get the principal end of the association var principalEnd = asmid.GetPrincipalEnd(); if (principalEnd == null) { return false; } foreach (var p1 in principalEnd.GetPropertyMappingIdentities()) { // find the "equivalent" property mapping identity in the referential constraint // this is the property mapping identity whose Principal side columns match the // Principal side columns on this property of the association end. AssociationPropertyIdentity rcEquivalent = null; foreach (var p2 in assRC.ReferentialConstraintIdentity.PropertyIdentities) { if (AssociationPropertyIdentityComparer.Instance.Compare(p1, p2) == 0) { rcEquivalent = p2; break; } } // if we couldn't find an identity in the RC whose "Principal" columns matched those // in the principal association end, return false if (rcEquivalent == null) { return false; } // // now check that for each database column in "Dependent" part of the association end, // (ie, each column mapped as part of the association set mapping) // it exists in the referential constraint's right columns (ie, the RC's dependent columns) // // Note that we don't do an equality check here, as the conceptual property in an RC // may be mapped to multiple tables, while the association set mapping will only ever be // mapped to one table. // foreach (var dc in p1.DependentColumns) { if (rcEquivalent.DependentColumns.Contains(dc) == false) { return false; } } } return true; }
internal static AssociationIdentity CreateAssociationIdentity(AssociationSetMapping asm) { var sSideEntitySet = asm.StoreEntitySet.Target as StorageEntitySet; if (null == sSideEntitySet) { // a null sSideEntitySet indicates an unresolved AssociationSetMapping // we treat this as equivalent to the AssociationSet being unmapped return null; } var assocId = new AssociationIdentityForAssociationSetMapping(); assocId._assocTable = DatabaseObject.CreateFromEntitySet(sSideEntitySet); foreach (var endProp in asm.EndProperties()) { var assocEndId = new AssociationEndIdentity(endProp); assocId.AddAssociationEndIdentity(assocEndId); } return assocId; }
internal static AssociationIdentity CreateAssociationIdentity(AssociationSetMapping asm) { var sSideEntitySet = asm.StoreEntitySet.Target as StorageEntitySet; if (null == sSideEntitySet) { // a null sSideEntitySet indicates an unresolved AssociationSetMapping // we treat this as equivalent to the AssociationSet being unmapped return(null); } var assocId = new AssociationIdentityForAssociationSetMapping(); assocId._assocTable = DatabaseObject.CreateFromEntitySet(sSideEntitySet); foreach (var endProp in asm.EndProperties()) { var assocEndId = new AssociationEndIdentity(endProp); assocId.AddAssociationEndIdentity(assocEndId); } return(assocId); }
/// <summary> /// returns true if the AssociationSetMapping is covered by the referential constraint. /// "covers" means that the /// 1. The columns mapped to the RC's principal keys match the columns mapped to the /// association's principal keys. /// 2. For each "pair" of properties that match between the RC & the ASM, the /// ASM's mapped column is contained in the dependent columns of the RC. /// </summary> private static bool IsCoveredBy(AssociationIdentityForReferentialConstraint assRC, AssociationIdentityForAssociationSetMapping asmid) { // get the principal end of the association var principalEnd = asmid.GetPrincipalEnd(); if (principalEnd == null) { return(false); } foreach (var p1 in principalEnd.GetPropertyMappingIdentities()) { // find the "equivalent" property mapping identity in the referential constraint // this is the property mapping identity whose Principal side columns match the // Principal side columns on this property of the association end. AssociationPropertyIdentity rcEquivalent = null; foreach (var p2 in assRC.ReferentialConstraintIdentity.PropertyIdentities) { if (AssociationPropertyIdentityComparer.Instance.Compare(p1, p2) == 0) { rcEquivalent = p2; break; } } // if we couldn't find an identity in the RC whose "Principal" columns matched those // in the principal association end, return false if (rcEquivalent == null) { return(false); } // // now check that for each database column in "Dependent" part of the association end, // (ie, each column mapped as part of the association set mapping) // it exists in the referential constraint's right columns (ie, the RC's dependent columns) // // Note that we don't do an equality check here, as the conceptual property in an RC // may be mapped to multiple tables, while the association set mapping will only ever be // mapped to one table. // foreach (var dc in p1.DependentColumns) { if (rcEquivalent.DependentColumns.Contains(dc) == false) { return(false); } } } return(true); }
/// <summary> /// See whether the AssociationIdentityForAssociationSetMapping other contains a "covering" for this /// i.e. check that the two AssociationIdentityForAssociationSetMapping objects have the same /// AssociationTable and that all AssociationEndIdentity's in this.Ends are covered by /// AssociationEndIdentity's in other.Ends (for definition of "covering" see /// method AssociationEndIdentity.IsCoveredBy(AssociationEndIdentity)) /// </summary> internal bool IsCoveredBy(AssociationIdentityForAssociationSetMapping other) { if (false == AssociationTable.Equals(other.AssociationTable)) { return false; } foreach (var thisEndId in Ends) { var foundCoveringEndId = false; foreach (var otherEndId in other.Ends) { // check whether thisEndId is covered by otherEndId if (thisEndId.IsCoveredBy(otherEndId)) { // have found an AssociationEndIdentity in other.Ends which covers thisEndId foundCoveringEndId = true; break; } } if (false == foundCoveringEndId) { // no covering AssociationEndIdentity was found for thisEndId in other.Ends return false; } } // all AssociationEndIdentity's in this.Ends were covered by an AssociationEndIdentity in other.Ends return true; }