internal bool IsEquivalentViaRefConstraint(MemberPath path1) { MemberPath assocPath0_1 = this; if (assocPath0_1.EdmType is EntityTypeBase || path1.EdmType is EntityTypeBase || (!MetadataHelper.IsNonRefSimpleMember(assocPath0_1.LeafEdmMember) || !MetadataHelper.IsNonRefSimpleMember(path1.LeafEdmMember))) { return(false); } AssociationSet extent1 = assocPath0_1.Extent as AssociationSet; AssociationSet extent2 = path1.Extent as AssociationSet; EntitySet extent3 = assocPath0_1.Extent as EntitySet; EntitySet extent4 = path1.Extent as EntitySet; bool flag = false; if (extent1 != null && extent2 != null) { if (!extent1.Equals((object)extent2)) { return(false); } flag = MemberPath.AreAssocationEndPathsEquivalentViaRefConstraint(assocPath0_1, path1, extent1); } else if (extent3 != null && extent4 != null) { foreach (AssociationSet associationsForEntitySet in MetadataHelper.GetAssociationsForEntitySets(extent3, extent4)) { if (MemberPath.AreAssocationEndPathsEquivalentViaRefConstraint(assocPath0_1.GetCorrespondingAssociationPath(associationsForEntitySet), path1.GetCorrespondingAssociationPath(associationsForEntitySet), associationsForEntitySet)) { flag = true; break; } } } else { AssociationSet assocSet = extent1 ?? extent2; MemberPath assocPath0_2 = assocPath0_1.Extent is AssociationSet ? assocPath0_1 : path1; MemberPath correspondingAssociationPath = (assocPath0_1.Extent is EntitySet ? assocPath0_1 : path1).GetCorrespondingAssociationPath(assocSet); flag = correspondingAssociationPath != null && MemberPath.AreAssocationEndPathsEquivalentViaRefConstraint(assocPath0_2, correspondingAssociationPath, assocSet); } return(flag); }
/// <summary> /// Returns true if this path and <paramref name="path1"/> are equivalent on the C-side via a referential constraint. /// </summary> internal bool IsEquivalentViaRefConstraint(MemberPath path1) { MemberPath path0 = this; // Now check if they are equivalent via referential constraint // For example, // * Person.pid and PersonAddress.Person.pid are equivalent // * Person.pid and PersonAddress.Address.pid are equivalent // * Person.pid and Address.pid are equivalent if there is a referential constraint // * PersonAddress.Person.pid and PersonAddress.Address.pid are // equivalent if there is a referential constraint // In short, Person.pid, Address.pid, PersonAddress.Address.pid, // PersonAddress.Person.pid are the same if (path0.EdmType is EntityTypeBase || path1.EdmType is EntityTypeBase || MetadataHelper.IsNonRefSimpleMember(path0.LeafEdmMember) == false || MetadataHelper.IsNonRefSimpleMember(path1.LeafEdmMember) == false) { // If the path corresponds to a top level extent only, ignore // it. Or if it is not a scalar return(false); } AssociationSet assocSet0 = path0.Extent as AssociationSet; AssociationSet assocSet1 = path1.Extent as AssociationSet; EntitySet entitySet0 = path0.Extent as EntitySet; EntitySet entitySet1 = path1.Extent as EntitySet; bool result = false; if (assocSet0 != null && assocSet1 != null) { // PersonAddress.Person.pid and PersonAddress.Address.pid case // Check if they are the same association or not if (assocSet0.Equals(assocSet1) == false) { return(false); } result = AreAssocationEndPathsEquivalentViaRefConstraint(path0, path1, assocSet0); } else if (entitySet0 != null && entitySet1 != null) { // Person.pid, Address.pid case // Find all the associations between the two sets. If the // fields are equivalent via any association + referential // constraint, return true List <AssociationSet> assocSets = MetadataHelper.GetAssociationsForEntitySets(entitySet0, entitySet1); foreach (AssociationSet assocSet in assocSets) { // For Person.pid, get PersonAddress.Person.pid or MemberPath assocEndPath0 = path0.GetCorrespondingAssociationPath(assocSet); MemberPath assocEndPath1 = path1.GetCorrespondingAssociationPath(assocSet); if (AreAssocationEndPathsEquivalentViaRefConstraint(assocEndPath0, assocEndPath1, assocSet)) { result = true; break; } } } else { // One of them is an assocSet and the other is an entity set AssociationSet assocSet = assocSet0 != null ? assocSet0 : assocSet1; EntitySet entitySet = entitySet0 != null ? entitySet0 : entitySet1; Debug.Assert(assocSet != null && entitySet != null, "One set must be association and the other must be entity set"); MemberPath assocEndPathA = path0.Extent is AssociationSet ? path0 : path1; MemberPath entityPath = path0.Extent is EntitySet ? path0 : path1; MemberPath assocEndPathB = entityPath.GetCorrespondingAssociationPath(assocSet); if (assocEndPathB == null) { //An EntitySet might participate in multiple AssociationSets //and this might not be the association set that defines the expected referential //constraint //Return false since this does not have any referential constraint specified result = false; } else { result = AreAssocationEndPathsEquivalentViaRefConstraint(assocEndPathA, assocEndPathB, assocSet); } } return(result); }