예제 #1
0
        internal void UpdateForeignKeyValues(IEntityWrapper dependentEntity, EntityKey principalKey)
        {
            ReferentialConstraint referentialConstraint = ((AssociationType)this.RelationMetadata).ReferentialConstraints[0];
            ObjectStateManager    objectStateManager    = this.ObjectContext.ObjectStateManager;

            objectStateManager.TransactionManager.BeginForeignKeyUpdate(this);
            try
            {
                EntitySet entitySet = ((AssociationSet)this.RelationshipSet).AssociationSetEnds[this.FromEndMember.Name].EntitySet;
                StateManagerTypeMetadata managerTypeMetadata = objectStateManager.GetOrAddStateManagerTypeMetadata(dependentEntity.IdentityType, entitySet);
                for (int index = 0; index < referentialConstraint.FromProperties.Count; ++index)
                {
                    object valueByName      = principalKey.FindValueByName(referentialConstraint.FromProperties[index].Name);
                    int    olayerMemberName = managerTypeMetadata.GetOrdinalforOLayerMemberName(referentialConstraint.ToProperties[index].Name);
                    object x = managerTypeMetadata.Member(olayerMemberName).GetValue(dependentEntity.Entity);
                    if (!ByValueEqualityComparer.Default.Equals(x, valueByName))
                    {
                        dependentEntity.SetCurrentValue(dependentEntity.ObjectStateEntry, managerTypeMetadata.Member(olayerMemberName), -1, dependentEntity.Entity, valueByName);
                    }
                }
                this.SetCachedForeignKey(principalKey, dependentEntity.ObjectStateEntry);
                if (this.WrappedOwner.ObjectStateEntry == null)
                {
                    return;
                }
                objectStateManager.ForgetEntryWithConceptualNull(this.WrappedOwner.ObjectStateEntry, false);
            }
            finally
            {
                objectStateManager.TransactionManager.EndForeignKeyUpdate();
            }
        }
예제 #2
0
        // 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
            var entityType = entityKey.GetEntitySet(m_translator.MetadataWorkspace).ElementType;
            var keyRowType = entityType.GetKeyRowType();

            var keyMetadata    = m_translator.GetExtractorMetadata(stateEntry.EntitySet, keyRowType);
            var keyMemberCount = keyRowType.Properties.Count;
            var keyValues      = new PropagatorResult[keyMemberCount];

            for (var ordinal = 0; ordinal < keyRowType.Properties.Count; ordinal++)
            {
                EdmMember keyMember = keyRowType.Properties[ordinal];
                // retrieve information about this key value
                var keyMemberInformation = keyMetadata.m_memberMap[ordinal];

                var 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).
                    var 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));
        }
예제 #3
0
        /// <summary>
        /// Takes key values from the given principal key and transfers them to the foreign key properties
        /// of the dependant entry.  This method requires a context, but does not require that either
        /// entity or key is in the context.  This allows it to work in NoTracking cases where we have the context
        /// but we're not tracked by that context.
        /// </summary>
        /// <param name="dependentEntity">The entity into which foreign key values will be written</param>
        /// <param name="principalEntity">The key from which key values will be obtained</param>
        internal void UpdateForeignKeyValues(IEntityWrapper dependentEntity, EntityKey principalKey)
        {
            Debug.Assert(dependentEntity.Entity != null, "dependentEntity.Entity == null");
            Debug.Assert(principalKey != null, "principalKey == null");
            Debug.Assert(!principalKey.IsTemporary, "Cannot update from a temp key");
            Debug.Assert(this.IsForeignKey, "cannot update foreign key values if the relationship is not a FK");
            ReferentialConstraint constraint = ((AssociationType)this.RelationMetadata).ReferentialConstraints[0];

            Debug.Assert(constraint != null, "null constraint");

            ObjectStateManager stateManager = ObjectContext.ObjectStateManager;

            stateManager.TransactionManager.BeginForeignKeyUpdate(this);
            try
            {
                EntitySet dependentEntitySet = ((AssociationSet)RelationshipSet).AssociationSetEnds[FromEndProperty.Name].EntitySet;
                StateManagerTypeMetadata dependentTypeMetadata = stateManager.GetOrAddStateManagerTypeMetadata(dependentEntity.IdentityType, dependentEntitySet);

                for (int i = 0; i < constraint.FromProperties.Count; i++)
                {
                    object value            = principalKey.FindValueByName(constraint.FromProperties[i].Name);
                    int    dependentOrdinal = dependentTypeMetadata.GetOrdinalforOLayerMemberName(constraint.ToProperties[i].Name);
                    object currentValue     = dependentTypeMetadata.Member(dependentOrdinal).GetValue(dependentEntity.Entity);
                    if (!ByValueEqualityComparer.Default.Equals(currentValue, value))
                    {
                        dependentEntity.SetCurrentValue(
                            dependentEntity.ObjectStateEntry,
                            dependentTypeMetadata.Member(dependentOrdinal),
                            -1,
                            dependentEntity.Entity,
                            value);
                    }
                }

                SetCachedForeignKey(principalKey, dependentEntity.ObjectStateEntry);
                if (WrappedOwner.ObjectStateEntry != null)
                {
                    stateManager.ForgetEntryWithConceptualNull(WrappedOwner.ObjectStateEntry, resetAllKeys: false);
                }
            }
            finally
            {
                stateManager.TransactionManager.EndForeignKeyUpdate();
            }
        }
        private PropagatorResult CreateEntityKeyResult(
            IEntityStateEntry stateEntry,
            EntityKey entityKey)
        {
            RowType           keyRowType        = entityKey.GetEntitySet(this.m_translator.MetadataWorkspace).ElementType.GetKeyRowType();
            ExtractorMetadata extractorMetadata = this.m_translator.GetExtractorMetadata(stateEntry.EntitySet, (StructuralType)keyRowType);

            PropagatorResult[] values = new PropagatorResult[keyRowType.Properties.Count];
            for (int memberOffset = 0; memberOffset < keyRowType.Properties.Count; ++memberOffset)
            {
                EdmMember property = (EdmMember)keyRowType.Properties[memberOffset];
                ExtractorMetadata.MemberInformation member = extractorMetadata.m_memberMap[memberOffset];
                int    identifierForMemberOffset           = this.m_translator.KeyManager.GetKeyIdentifierForMemberOffset(entityKey, memberOffset, keyRowType.Properties.Count);
                object obj = !entityKey.IsTemporary ? entityKey.FindValueByName(property.Name) : stateEntry.StateManager.GetEntityStateEntry(entityKey).CurrentValues[property.Name];
                values[memberOffset] = PropagatorResult.CreateKeyValue(member.Flags, obj, stateEntry, identifierForMemberOffset);
            }
            return(PropagatorResult.CreateStructuralValue(values, extractorMetadata.m_type, false));
        }
예제 #5
0
        /// <summary>
        /// Takes key values from the given principal key and transfers them to the foreign key properties
        /// of the dependant entry.  This method requires a context, but does not require that either
        /// entity or key is in the context.  This allows it to work in NoTracking cases where we have the context
        /// but we're not tracked by that context.
        /// </summary>
        /// <param name="dependentEntity">The entity into which foreign key values will be written</param>
        /// <param name="principalEntity">The key from which key values will be obtained</param>
        internal void UpdateForeignKeyValues(IEntityWrapper dependentEntity, EntityKey principalKey)
        {
            Debug.Assert(dependentEntity.Entity != null, "dependentEntity.Entity == null");
            Debug.Assert(principalKey != null, "principalKey == null");
            Debug.Assert(!principalKey.IsTemporary, "Cannot update from a temp key");
            Debug.Assert(IsForeignKey, "cannot update foreign key values if the relationship is not a FK");
            var constraint = ((AssociationType)RelationMetadata).ReferentialConstraints[0];
            Debug.Assert(constraint != null, "null constraint");

            var stateManager = ObjectContext.ObjectStateManager;
            stateManager.TransactionManager.BeginForeignKeyUpdate(this);
            try
            {
                var dependentEntitySet = ((AssociationSet)RelationshipSet).AssociationSetEnds[FromEndMember.Name].EntitySet;
                var dependentTypeMetadata = stateManager.GetOrAddStateManagerTypeMetadata(dependentEntity.IdentityType, dependentEntitySet);

                for (var i = 0; i < constraint.FromProperties.Count; i++)
                {
                    var value = principalKey.FindValueByName(constraint.FromProperties[i].Name);
                    var dependentOrdinal = dependentTypeMetadata.GetOrdinalforOLayerMemberName(constraint.ToProperties[i].Name);
                    var currentValue = dependentTypeMetadata.Member(dependentOrdinal).GetValue(dependentEntity.Entity);
                    if (!ByValueEqualityComparer.Default.Equals(currentValue, value))
                    {
                        dependentEntity.SetCurrentValue(
                            dependentEntity.ObjectStateEntry,
                            dependentTypeMetadata.Member(dependentOrdinal),
                            -1,
                            dependentEntity.Entity,
                            value);
                    }
                }

                SetCachedForeignKey(principalKey, dependentEntity.ObjectStateEntry);
                if (WrappedOwner.ObjectStateEntry != null)
                {
                    stateManager.ForgetEntryWithConceptualNull(WrappedOwner.ObjectStateEntry, resetAllKeys: false);
                }
            }
            finally
            {
                stateManager.TransactionManager.EndForeignKeyUpdate();
            }
        }
        // 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
            var entityType = entityKey.GetEntitySet(m_translator.MetadataWorkspace).ElementType;
            var keyRowType = entityType.GetKeyRowType();

            var keyMetadata = m_translator.GetExtractorMetadata(stateEntry.EntitySet, keyRowType);
            var keyMemberCount = keyRowType.Properties.Count;
            var keyValues = new PropagatorResult[keyMemberCount];

            for (var ordinal = 0; ordinal < keyRowType.Properties.Count; ordinal++)
            {
                EdmMember keyMember = keyRowType.Properties[ordinal];
                // retrieve information about this key value
                var keyMemberInformation = keyMetadata.m_memberMap[ordinal];

                var 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).
                    var 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);
        }