// Note that this is called only for association ends. Entities have key values inline. private PropagatorResult CreateEntityKeyResult(IEntityStateEntry stateEntry, EntityKey entityKey) { // get metadata for key EntityType entityType = entityKey.GetEntitySet(m_translator.MetadataWorkspace).ElementType; RowType keyRowType = entityType.GetKeyRowType(m_translator.MetadataWorkspace); ExtractorMetadata keyMetadata = m_translator.GetExtractorMetadata(stateEntry.EntitySet, keyRowType); int keyMemberCount = keyRowType.Properties.Count; PropagatorResult[] keyValues = new PropagatorResult[keyMemberCount]; for (int ordinal = 0; ordinal < keyRowType.Properties.Count; ordinal++) { EdmMember keyMember = keyRowType.Properties[ordinal]; // retrieve information about this key value MemberInformation keyMemberInformation = keyMetadata.m_memberMap[ordinal]; int keyIdentifier = m_translator.KeyManager.GetKeyIdentifierForMemberOffset(entityKey, ordinal, keyRowType.Properties.Count); object keyValue = null; if (entityKey.IsTemporary) { // If the EntityKey is temporary, we need to retrieve the appropriate // key value from the entity itself (or in this case, the IEntityStateEntry). IEntityStateEntry entityEntry = stateEntry.StateManager.GetEntityStateEntry(entityKey); Debug.Assert(entityEntry.State == EntityState.Added, "The corresponding entry for a temp EntityKey should be in the Added State."); keyValue = entityEntry.CurrentValues[keyMember.Name]; } else { // Otherwise, we extract the value from within the EntityKey. keyValue = entityKey.FindValueByName(keyMember.Name); } Debug.Assert(keyValue != null, "keyValue should've been retrieved."); // construct propagator result keyValues[ordinal] = PropagatorResult.CreateKeyValue( keyMemberInformation.Flags, keyValue, stateEntry, keyIdentifier); // see UpdateTranslator.Identifiers for information on key identifiers and ordinals } return(PropagatorResult.CreateStructuralValue(keyValues, keyMetadata.m_type, false)); }
/// <summary> /// Converts a record to a propagator result /// </summary> /// <param name="stateEntry">state manager entry containing the record</param> /// <param name="isModified">Indicates whether the root element is modified (i.e., whether the type has changed)</param> /// <param name="record">Record to convert</param> /// <param name="useCurrentValues">Indicates whether we are retrieving current or original values.</param> /// <param name="translator">Translator for session context; registers new metadata for the record type if none /// exists</param> /// <param name="modifiedPropertiesBehavior">Indicates how to determine whether a property is modified.</param> /// <returns>Result corresponding to the given record</returns> internal static PropagatorResult ExtractResultFromRecord(IEntityStateEntry stateEntry, bool isModified, IExtendedDataRecord record, bool useCurrentValues, UpdateTranslator translator, ModifiedPropertiesBehavior modifiedPropertiesBehavior) { StructuralType structuralType = (StructuralType)record.DataRecordInfo.RecordType.EdmType; ExtractorMetadata metadata = translator.GetExtractorMetadata(stateEntry.EntitySet, structuralType); EntityKey key = stateEntry.EntityKey; PropagatorResult[] nestedValues = new PropagatorResult[record.FieldCount]; for (int ordinal = 0; ordinal < nestedValues.Length; ordinal++) { nestedValues[ordinal] = metadata.RetrieveMember(stateEntry, record, useCurrentValues, key, ordinal, modifiedPropertiesBehavior); } return(PropagatorResult.CreateStructuralValue(nestedValues, structuralType, isModified)); }
private PropagatorResult ConvertStateEntryToPropagatorResult(IEntityStateEntry stateEntry, bool useCurrentValues, ModifiedPropertiesBehavior modifiedPropertiesBehavior) { try { EntityUtil.CheckArgumentNull(stateEntry, "stateEntry"); IExtendedDataRecord record = useCurrentValues ? EntityUtil.CheckArgumentNull(stateEntry.CurrentValues as IExtendedDataRecord, "stateEntry.CurrentValues") : EntityUtil.CheckArgumentNull(stateEntry.OriginalValues as IExtendedDataRecord, "stateEntry.OriginalValues"); bool isModified = false; // the root of the state entry is unchanged because the type is static return(ExtractorMetadata.ExtractResultFromRecord(stateEntry, isModified, record, useCurrentValues, m_updateTranslator, modifiedPropertiesBehavior)); } catch (Exception e) { if (UpdateTranslator.RequiresContext(e)) { throw EntityUtil.Update(Strings.Update_ErrorLoadingRecord, e, stateEntry); } throw; } }
/// <summary> /// Gets a metadata wrapper for the given type. The wrapper makes /// certain tasks in the update pipeline more efficient. /// </summary> /// <param name="type">Structural type</param> /// <returns>Metadata wrapper</returns> internal ExtractorMetadata GetExtractorMetadata(EntitySetBase entitySetBase, StructuralType type) { ExtractorMetadata metadata; var key = Tuple.Create(entitySetBase, type); if (!m_extractorMetadata.TryGetValue(key, out metadata)) { metadata = new ExtractorMetadata(entitySetBase, type, this); m_extractorMetadata.Add(key, metadata); } return metadata; }