/// <summary> /// Given the <paramref name="prefix"/>, determines the slots in <paramref name="slots"/> that correspond to the entity key for the entity set or the /// association set end. Returns the list of slots. Returns null if even one of the key slots is not present in slots. /// </summary> /// <param name="prefix">corresponds to an entity set or an association end</param> internal static List <MemberProjectedSlot> GetKeySlots(IEnumerable <MemberProjectedSlot> slots, MemberPath prefix) { // Get the entity type of the hosted end or entity set EntitySet entitySet = prefix.EntitySet; Debug.Assert(entitySet != null, "Prefix must have associated entity set"); List <ExtentKey> keys = ExtentKey.GetKeysForEntityType(prefix, entitySet.ElementType); Debug.Assert(keys.Count > 0, "No keys for entity?"); Debug.Assert(keys.Count == 1, "Currently, we only support primary keys"); // Get the slots for the key List <MemberProjectedSlot> keySlots = GetSlots(slots, keys[0].KeyFields); return(keySlots); }
// effects: Returns an error record if the keys of the extent/associationSet being mapped are // present in the projected slots of this query. Returns null // otherwise. ownerCell indicates the cell that owns this and // resourceString is a resource used for error messages internal ErrorLog.Record VerifyKeysPresent(Cell ownerCell, Func <object, object, string> formatEntitySetMessage, Func <object, object, object, string> formatAssociationSetMessage, ViewGenErrorCode errorCode) { List <MemberPath> prefixes = new List <MemberPath>(1); // Keep track of the key corresponding to each prefix List <ExtentKey> keys = new List <ExtentKey>(1); if (Extent is EntitySet) { // For entity set just get the full path of the key properties MemberPath prefix = new MemberPath(Extent); prefixes.Add(prefix); EntityType entityType = (EntityType)Extent.ElementType; List <ExtentKey> entitySetKeys = ExtentKey.GetKeysForEntityType(prefix, entityType); Debug.Assert(entitySetKeys.Count == 1, "Currently, we only support primary keys"); keys.Add(entitySetKeys[0]); } else { AssociationSet relationshipSet = (AssociationSet)Extent; // For association set, get the full path of the key // properties of each end foreach (AssociationSetEnd relationEnd in relationshipSet.AssociationSetEnds) { AssociationEndMember assocEndMember = relationEnd.CorrespondingAssociationEndMember; MemberPath prefix = new MemberPath(relationshipSet, assocEndMember); prefixes.Add(prefix); List <ExtentKey> endKeys = ExtentKey.GetKeysForEntityType(prefix, MetadataHelper.GetEntityTypeForEnd(assocEndMember)); Debug.Assert(endKeys.Count == 1, "Currently, we only support primary keys"); keys.Add(endKeys[0]); } } for (int i = 0; i < prefixes.Count; i++) { MemberPath prefix = prefixes[i]; // Get all or none key slots that are being projected in this cell query List <MemberProjectedSlot> keySlots = MemberProjectedSlot.GetKeySlots(GetMemberProjectedSlots(), prefix); if (keySlots == null) { ExtentKey key = keys[i]; string message; if (Extent is EntitySet) { string keyPropertiesString = MemberPath.PropertiesToUserString(key.KeyFields, true); message = formatEntitySetMessage(keyPropertiesString, Extent.Name); } else { string endName = prefix.RootEdmMember.Name; string keyPropertiesString = MemberPath.PropertiesToUserString(key.KeyFields, false); message = formatAssociationSetMessage(keyPropertiesString, endName, Extent.Name); } ErrorLog.Record error = new ErrorLog.Record(true, errorCode, message, ownerCell, String.Empty); return(error); } } return(null); }