// effects: Returns the key for entityType prefixed with prefix (for // its memberPath) internal static ExtentKey GetPrimaryKeyForEntityType(MemberPath prefix, EntityType entityType) { var keyFields = new List<MemberPath>(); foreach (var keyMember in entityType.KeyMembers) { Debug.Assert(keyMember != null, "Bogus key member in metadata"); keyFields.Add(new MemberPath(prefix, keyMember)); } // Just have one key for now var key = new ExtentKey(keyFields); return key; }
// effects: Returns a key correspnding to all the fields in different // ends of relationtype prefixed with "prefix" internal static ExtentKey GetKeyForRelationType(MemberPath prefix, AssociationType relationType) { var keyFields = new List<MemberPath>(); foreach (var endMember in relationType.AssociationEndMembers) { var endPrefix = new MemberPath(prefix, endMember); var entityType = MetadataHelper.GetEntityTypeForEnd(endMember); var primaryKey = GetPrimaryKeyForEntityType(endPrefix, entityType); keyFields.AddRange(primaryKey.KeyFields); } var key = new ExtentKey(keyFields); return key; }
// 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) { var prefixes = new List <MemberPath>(1); // Keep track of the key corresponding to each prefix var keys = new List <ExtentKey>(1); if (Extent is EntitySet) { // For entity set just get the full path of the key properties var prefix = new MemberPath(Extent); prefixes.Add(prefix); var entityType = (EntityType)Extent.ElementType; var entitySetKeys = ExtentKey.GetKeysForEntityType(prefix, entityType); Debug.Assert(entitySetKeys.Count == 1, "Currently, we only support primary keys"); keys.Add(entitySetKeys[0]); } else { var relationshipSet = (AssociationSet)Extent; // For association set, get the full path of the key // properties of each end foreach (var relationEnd in relationshipSet.AssociationSetEnds) { var assocEndMember = relationEnd.CorrespondingAssociationEndMember; var prefix = new MemberPath(relationshipSet, assocEndMember); prefixes.Add(prefix); var endKeys = ExtentKey.GetKeysForEntityType( prefix, MetadataHelper.GetEntityTypeForEnd(assocEndMember)); Debug.Assert(endKeys.Count == 1, "Currently, we only support primary keys"); keys.Add(endKeys[0]); } } for (var i = 0; i < prefixes.Count; i++) { var prefix = prefixes[i]; // Get all or none key slots that are being projected in this cell query var keySlots = MemberProjectedSlot.GetKeySlots(GetMemberProjectedSlots(), prefix); if (keySlots == null) { var key = keys[i]; string message; if (Extent is EntitySet) { var keyPropertiesString = MemberPath.PropertiesToUserString(key.KeyFields, true); message = formatEntitySetMessage(keyPropertiesString, Extent.Name); } else { var endName = prefix.RootEdmMember.Name; var keyPropertiesString = MemberPath.PropertiesToUserString(key.KeyFields, false); message = formatAssociationSetMessage(keyPropertiesString, endName, Extent.Name); } var error = new ErrorLog.Record(errorCode, message, ownerCell, String.Empty); return(error); } } return(null); }
// requires: this to correspond to a cell relation for an association set (m_cellQuery.Extent) // effects: Adds any key constraints present in this relation in // constraints private void PopulateKeyConstraintsForRelationshipSet(BasicSchemaConstraints constraints) { var relationshipSet = m_cellQuery.Extent as AssociationSet; // Gather all members of all keys // CHANGE_ADYA_FEATURE_KEYS: assume that an Entity has exactly one key. Otherwise we // have to take a cross-product of all keys // Keep track of all the key members for the association in a set // so that if no end corresponds to a key, we use all the members // to form the key var associationKeyMembers = new Set<MemberPath>(MemberPath.EqualityComparer); var hasAnEndThatFormsKey = false; // Determine the keys of each end. If the end forms a key, add it // as a key to the set foreach (var end in relationshipSet.AssociationSetEnds) { var endMember = end.CorrespondingAssociationEndMember; var prefix = new MemberPath(relationshipSet, endMember); var keys = ExtentKey.GetKeysForEntityType(prefix, end.EntitySet.ElementType); Debug.Assert(keys.Count > 0, "No keys for entity?"); Debug.Assert(keys.Count == 1, "Currently, we only support primary keys"); if (MetadataHelper.DoesEndFormKey(relationshipSet, endMember)) { // This end has is a key end AddKeyConstraints(keys, constraints); hasAnEndThatFormsKey = true; } // Add the members of the (only) key to associationKey associationKeyMembers.AddRange(keys[0].KeyFields); } // If an end forms a key then that key implies the full key if (false == hasAnEndThatFormsKey) { // No end is a key -- take all the end members and make a key // based on that var key = new ExtentKey(associationKeyMembers); var keys = new[] { key }; AddKeyConstraints(keys, constraints); } }