/// <summary> /// See whether the AssociationPropertyIdentity otherApi contains a "covering" for this /// AssociationPropertyIdentity i.e. see whether otherApi contains at least the same /// principal DatabaseColumns (but possibly more) _and_ at least the same dependent /// DatabaseColumns (but possibly more). /// This allows for treating these AssociationPropertyIdentity's as identical for the purposes /// of Update Model even if a given C-side property has been mapped to more than 1 S-side property. /// </summary> internal bool IsCoveredBy(AssociationPropertyIdentity otherApi) { // check whether all this.PrincipalColumns are contained in otherApi.PrincipalColumns var thisPrincipalColumns = PrincipalColumns; var otherPrincipalColumns = otherApi.PrincipalColumns; if (false == otherPrincipalColumns.ContainsAll(thisPrincipalColumns)) { // thisPrincipalColumns has at least one DatabaseColumn which is not // in otherPrincipalColumns, so otherApi does not cover thisApi return(false); } // check whether all this.DependentColumns are contained in otherApi.DependentColumns var thisDependentColumns = DependentColumns; var otherDependentColumns = otherApi.DependentColumns; if (false == otherDependentColumns.ContainsAll(thisDependentColumns)) { // thisDependentColumns has at least one DatabaseColumn which is not // in otherDependentColumns, so otherApi does not cover thisApi return(false); } // the Principal and Dependent DatabaseColumns for this are covered by the Principal // and Dependent DatabaseColumns in otherApi return(true); }
/// <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 ReferentialConstraintIdentity CreateReferentialConstraintIdentity(ReferentialConstraint referentialConstraint) { if (referentialConstraint == null) { Debug.Fail("null referential constraint"); } else { var rcid = new ReferentialConstraintIdentity(); rcid._propertyIdentities = AssociationPropertyIdentity.CreateIdentitiesFromReferentialConstraint(referentialConstraint); return(rcid); } return(null); }
internal static SortedListAllowDupes <AssociationPropertyIdentity> CreateIdentitiesFromAssociationEndProperty(EndProperty endProp) { var props = new SortedListAllowDupes <AssociationPropertyIdentity>(AssociationPropertyIdentityComparer.Instance); foreach (var sProp in endProp.ScalarProperties()) { var id = new AssociationPropertyIdentity(); var keyProperty = sProp.Name.Target as ConceptualProperty; id.PrincipalColumns = GetMappedColumnsForConceptualProperty(keyProperty); id.DependentColumns = new SortedListAllowDupes <DatabaseColumn>(new DatabaseColumnComparer()); var sSideProperty = sProp.ColumnName.Target; if (null != sSideProperty) { var stc = DatabaseColumn.CreateFromProperty(sSideProperty); id.DependentColumns.Add(stc); props.Add(id); } } return(props); }
internal static SortedListAllowDupes <AssociationPropertyIdentity> CreateIdentitiesFromReferentialConstraint( ReferentialConstraint referentialConstraint) { var principal = referentialConstraint.Principal; var dependent = referentialConstraint.Dependent; var identities = new SortedListAllowDupes <AssociationPropertyIdentity>(AssociationPropertyIdentityComparer.Instance); if (principal != null && dependent != null) { // TODO: deal with case where counts differ. if (principal.PropertyRefs.Count == dependent.PropertyRefs.Count) { var pPropRefs = principal.PropertyRefs.GetEnumerator(); var dPropRefs = dependent.PropertyRefs.GetEnumerator(); while (pPropRefs.MoveNext() && dPropRefs.MoveNext()) { var pProp = pPropRefs.Current.Name.Target as ConceptualProperty; var dProp = dPropRefs.Current.Name.Target as ConceptualProperty; if (pProp != null && dProp != null) { var id = new AssociationPropertyIdentity(); id.PrincipalColumns = GetMappedColumnsForConceptualProperty(pProp); id.DependentColumns = GetMappedColumnsForConceptualProperty(dProp); identities.Add(id); } } } } return(identities); }
internal AssociationEndIdentity(EndProperty endProp) { _propertyIdentities = AssociationPropertyIdentity.CreateIdentitiesFromAssociationEndProperty(endProp); }