private static bool TryGetWithRelationship( StorageAssociationSetMapping colocatedAssociationSetMap, EntitySetBase thisExtent, MemberPath sRootNode, ref List <SlotInfo> foreignKeySlots, out WithRelationship withRelationship) { DebugCheck.NotNull(foreignKeySlots); withRelationship = null; //Get the map for foreign key end var foreignKeyEndMap = GetForeignKeyEndMapFromAssocitionMap(colocatedAssociationSetMap); if (foreignKeyEndMap == null || foreignKeyEndMap.EndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many) { return(false); } var toEnd = (AssociationEndMember)foreignKeyEndMap.EndMember; var fromEnd = MetadataHelper.GetOtherAssociationEnd(toEnd); var toEndEntityType = (EntityType)((RefType)(toEnd.TypeUsage.EdmType)).ElementType; var fromEndEntityType = (EntityType)(((RefType)fromEnd.TypeUsage.EdmType).ElementType); // Get the member path for AssociationSet var associationSet = (AssociationSet)colocatedAssociationSetMap.Set; var prefix = new MemberPath(associationSet, toEnd); // Collect the member paths for edm scalar properties that belong to the target entity key. // These will be used as part of WITH RELATIONSHIP. // Get the key properties from edm type since the query parser depends on the order of key members var propertyMaps = foreignKeyEndMap.Properties.Cast <StorageScalarPropertyMapping>(); var toEndEntityKeyMemberPaths = new List <MemberPath>(); foreach (EdmProperty edmProperty in toEndEntityType.KeyMembers) { var scalarPropertyMaps = propertyMaps.Where(propMap => (propMap.EdmProperty.Equals(edmProperty))); Debug.Assert(scalarPropertyMaps.Count() == 1, "Can't Map the same column multiple times in the same end"); var scalarPropertyMap = scalarPropertyMaps.First(); // Create SlotInfo for Freign Key member that needs to be projected. var sSlot = new MemberProjectedSlot(new MemberPath(sRootNode, scalarPropertyMap.ColumnProperty)); var endMemberKeyPath = new MemberPath(prefix, edmProperty); toEndEntityKeyMemberPaths.Add(endMemberKeyPath); foreignKeySlots.Add(new SlotInfo(true, true, sSlot, endMemberKeyPath)); } // Parent assignable from child: Ensures they are in the same hierarchy. if (thisExtent.ElementType.IsAssignableFrom(fromEndEntityType)) { // Now create the WITH RELATIONSHIP with all the needed info. withRelationship = new WithRelationship( associationSet, fromEnd, fromEndEntityType, toEnd, toEndEntityType, toEndEntityKeyMemberPaths); return(true); } else { return(false); } }
private static bool TryGetWithRelationship( AssociationSetMapping colocatedAssociationSetMap, EntitySetBase thisExtent, MemberPath sRootNode, ref List <SlotInfo> foreignKeySlots, out WithRelationship withRelationship) { withRelationship = (WithRelationship)null; EndPropertyMapping fromAssocitionMap = LeafCellTreeNode.GetForeignKeyEndMapFromAssocitionMap(colocatedAssociationSetMap); if (fromAssocitionMap == null || fromAssocitionMap.AssociationEnd.RelationshipMultiplicity == RelationshipMultiplicity.Many) { return(false); } AssociationEndMember associationEnd = fromAssocitionMap.AssociationEnd; AssociationEndMember otherAssociationEnd = MetadataHelper.GetOtherAssociationEnd(associationEnd); EntityType elementType1 = (EntityType)((RefType)associationEnd.TypeUsage.EdmType).ElementType; EntityType elementType2 = (EntityType)((RefType)otherAssociationEnd.TypeUsage.EdmType).ElementType; AssociationSet set = (AssociationSet)colocatedAssociationSetMap.Set; MemberPath prefix = new MemberPath((EntitySetBase)set, (EdmMember)associationEnd); IEnumerable <ScalarPropertyMapping> source = fromAssocitionMap.PropertyMappings.Cast <ScalarPropertyMapping>(); List <MemberPath> memberPathList = new List <MemberPath>(); foreach (EdmProperty keyMember in elementType1.KeyMembers) { EdmProperty edmProperty = keyMember; ScalarPropertyMapping scalarPropertyMapping = source.Where <ScalarPropertyMapping>((Func <ScalarPropertyMapping, bool>)(propMap => propMap.Property.Equals((object)edmProperty))).First <ScalarPropertyMapping>(); MemberProjectedSlot memberProjectedSlot = new MemberProjectedSlot(new MemberPath(sRootNode, (EdmMember)scalarPropertyMapping.Column)); MemberPath outputMember = new MemberPath(prefix, (EdmMember)edmProperty); memberPathList.Add(outputMember); foreignKeySlots.Add(new SlotInfo(true, true, (ProjectedSlot)memberProjectedSlot, outputMember)); } if (!thisExtent.ElementType.IsAssignableFrom((EdmType)elementType2)) { return(false); } withRelationship = new WithRelationship(set, otherAssociationEnd, elementType2, associationEnd, elementType1, (IEnumerable <MemberPath>)memberPathList); return(true); }