Exemplo n.º 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();
            }
        }
Exemplo n.º 2
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();
            }
        }
Exemplo n.º 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(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();
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Takes key values from the given principal entity and transfers them to the foreign key properties
        /// of the dependant entry.  This method requires a context, but does not require that either
        /// entity 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 entity from which key values will be obtained</param>
        /// <param name="changedFKs">If non-null, then keeps track of FKs that have already been set such that an exception can be thrown if we find conflicting values</param>
        /// <param name="forceChange">If true, then the property setter is called even if FK values already match,
        ///                           which causes the FK properties to be marked as modified.</param>
        internal void UpdateForeignKeyValues(
            IEntityWrapper dependentEntity, IEntityWrapper principalEntity, Dictionary<int, object> changedFKs, bool forceChange)
        {
            Debug.Assert(dependentEntity.Entity != null, "dependentEntity.Entity == null");
            Debug.Assert(principalEntity.Entity != null, "principalEntity.Entity == null");
            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 isUnchangedDependent = (object)WrappedOwner.EntityKey != null &&
                                       !WrappedOwner.EntityKey.IsTemporary &&
                                       IsDependentEndOfReferentialConstraint(checkIdentifying: true);

            var stateManager = ObjectContext.ObjectStateManager;
            stateManager.TransactionManager.BeginForeignKeyUpdate(this);
            try
            {
                var principalEntitySet = ((AssociationSet)RelationshipSet).AssociationSetEnds[ToEndMember.Name].EntitySet;
                var principalTypeMetadata = stateManager.GetOrAddStateManagerTypeMetadata(principalEntity.IdentityType, principalEntitySet);

                var dependentEntitySet = ((AssociationSet)RelationshipSet).AssociationSetEnds[FromEndMember.Name].EntitySet;
                var dependentTypeMetadata = stateManager.GetOrAddStateManagerTypeMetadata(dependentEntity.IdentityType, dependentEntitySet);

                var principalProps = constraint.FromProperties;
                var numValues = principalProps.Count;
                string[] keyNames = null;
                object[] values = null;
                if (numValues > 1)
                {
                    keyNames = principalEntitySet.ElementType.KeyMemberNames;
                    values = new object[numValues];
                }
                for (var i = 0; i < numValues; i++)
                {
                    var principalOrdinal = principalTypeMetadata.GetOrdinalforOLayerMemberName(principalProps[i].Name);
                    var value = principalTypeMetadata.Member(principalOrdinal).GetValue(principalEntity.Entity);
                    var dependentOrdinal = dependentTypeMetadata.GetOrdinalforOLayerMemberName(constraint.ToProperties[i].Name);
                    var valueChanging =
                        !ByValueEqualityComparer.Default.Equals(
                            dependentTypeMetadata.Member(dependentOrdinal).GetValue(dependentEntity.Entity), value);
                    if (forceChange || valueChanging)
                    {
                        if (isUnchangedDependent)
                        {
                            ValidateSettingRIConstraints(
                                principalEntity, settingToNull: value == null, changingForeignKeyValue: valueChanging);
                        }
                        // If we're tracking FK values that have already been set, then compare the value we are about to set
                        // to the value we previously set for this ordinal, if such a value exists.  If they don't match then
                        // it means that we got conflicting FK values from two different PKs and we should throw.
                        if (changedFKs != null)
                        {
                            object previouslySetValue;
                            if (changedFKs.TryGetValue(dependentOrdinal, out previouslySetValue))
                            {
                                if (!ByValueEqualityComparer.Default.Equals(previouslySetValue, value))
                                {
                                    throw new InvalidOperationException(Strings.Update_ReferentialConstraintIntegrityViolation);
                                }
                            }
                            else
                            {
                                changedFKs[dependentOrdinal] = value;
                            }
                        }
                        dependentEntity.SetCurrentValue(
                            dependentEntity.ObjectStateEntry,
                            dependentTypeMetadata.Member(dependentOrdinal),
                            -1,
                            dependentEntity.Entity,
                            value);
                    }

                    if (numValues > 1)
                    {
                        var keyIndex = Array.IndexOf(keyNames, principalProps[i].Name);
                        Debug.Assert(keyIndex >= 0 && keyIndex < numValues, "Could not find constraint prop name in entity set key names");
                        values[keyIndex] = value;
                    }
                    else
                    {
                        SetCachedForeignKey(new EntityKey(principalEntitySet, value), dependentEntity.ObjectStateEntry);
                    }
                }

                if (numValues > 1)
                {
                    SetCachedForeignKey(new EntityKey(principalEntitySet, values), dependentEntity.ObjectStateEntry);
                }
                if (WrappedOwner.ObjectStateEntry != null)
                {
                    stateManager.ForgetEntryWithConceptualNull(WrappedOwner.ObjectStateEntry, resetAllKeys: false);
                }
            }
            finally
            {
                stateManager.TransactionManager.EndForeignKeyUpdate();
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Takes key values from the given principal entity and transfers them to the foreign key properties
        /// of the dependant entry.  This method requires a context, but does not require that either
        /// entity 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 entity from which key values will be obtained</param>
        /// <param name="changedFKs">If non-null, then keeps track of FKs that have already been set such that an exception can be thrown if we find conflicting values</param>
        /// <param name="forceChange">If true, then the property setter is called even if FK values already match,
        ///                           which causes the FK properties to be marked as modified.</param>
        internal void UpdateForeignKeyValues(IEntityWrapper dependentEntity, IEntityWrapper principalEntity, Dictionary <int, object> changedFKs, bool forceChange)
        {
            Debug.Assert(dependentEntity.Entity != null, "dependentEntity.Entity == null");
            Debug.Assert(principalEntity.Entity != null, "principalEntity.Entity == null");
            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");

            bool isUnchangedDependent = (object)WrappedOwner.EntityKey != null &&
                                        !WrappedOwner.EntityKey.IsTemporary &&
                                        IsDependentEndOfReferentialConstraint(checkIdentifying: true);

            ObjectStateManager stateManager = ObjectContext.ObjectStateManager;

            stateManager.TransactionManager.BeginForeignKeyUpdate(this);
            try
            {
                EntitySet principalEntitySet = ((AssociationSet)RelationshipSet).AssociationSetEnds[ToEndMember.Name].EntitySet;
                StateManagerTypeMetadata principalTypeMetadata = stateManager.GetOrAddStateManagerTypeMetadata(principalEntity.IdentityType, principalEntitySet);

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

                var      principalProps = constraint.FromProperties;
                int      numValues      = principalProps.Count;
                string[] keyNames       = null;
                object[] values         = null;
                if (numValues > 1)
                {
                    keyNames = principalEntitySet.ElementType.KeyMemberNames;
                    values   = new object[numValues];
                }
                for (int i = 0; i < numValues; i++)
                {
                    int    principalOrdinal = principalTypeMetadata.GetOrdinalforOLayerMemberName(principalProps[i].Name);
                    object value            = principalTypeMetadata.Member(principalOrdinal).GetValue(principalEntity.Entity);
                    int    dependentOrdinal = dependentTypeMetadata.GetOrdinalforOLayerMemberName(constraint.ToProperties[i].Name);
                    bool   valueChanging    = !ByValueEqualityComparer.Default.Equals(dependentTypeMetadata.Member(dependentOrdinal).GetValue(dependentEntity.Entity), value);
                    if (forceChange || valueChanging)
                    {
                        if (isUnchangedDependent)
                        {
                            ValidateSettingRIConstraints(principalEntity, settingToNull: value == null, changingForeignKeyValue: valueChanging);
                        }
                        // If we're tracking FK values that have already been set, then compare the value we are about to set
                        // to the value we previously set for this ordinal, if such a value exists.  If they don't match then
                        // it means that we got conflicting FK values from two different PKs and we should throw.
                        if (changedFKs != null)
                        {
                            object previouslySetValue;
                            if (changedFKs.TryGetValue(dependentOrdinal, out previouslySetValue))
                            {
                                if (!ByValueEqualityComparer.Default.Equals(previouslySetValue, value))
                                {
                                    throw new InvalidOperationException(System.Data.Entity.Strings.Update_ReferentialConstraintIntegrityViolation);
                                }
                            }
                            else
                            {
                                changedFKs[dependentOrdinal] = value;
                            }
                        }
                        dependentEntity.SetCurrentValue(
                            dependentEntity.ObjectStateEntry,
                            dependentTypeMetadata.Member(dependentOrdinal),
                            -1,
                            dependentEntity.Entity,
                            value);
                    }

                    if (numValues > 1)
                    {
                        int keyIndex = Array.IndexOf(keyNames, principalProps[i].Name);
                        Debug.Assert(keyIndex >= 0 && keyIndex < numValues, "Could not find constraint prop name in entity set key names");
                        values[keyIndex] = value;
                    }
                    else
                    {
                        SetCachedForeignKey(new EntityKey(principalEntitySet, value), dependentEntity.ObjectStateEntry);
                    }
                }

                if (numValues > 1)
                {
                    SetCachedForeignKey(new EntityKey(principalEntitySet, values), dependentEntity.ObjectStateEntry);
                }
                if (WrappedOwner.ObjectStateEntry != null)
                {
                    stateManager.ForgetEntryWithConceptualNull(WrappedOwner.ObjectStateEntry, resetAllKeys: false);
                }
            }
            finally
            {
                stateManager.TransactionManager.EndForeignKeyUpdate();
            }
        }
Exemplo n.º 6
0
        internal void UpdateForeignKeyValues(
            IEntityWrapper dependentEntity,
            IEntityWrapper principalEntity,
            Dictionary <int, object> changedFKs,
            bool forceChange)
        {
            ReferentialConstraint referentialConstraint = ((AssociationType)this.RelationMetadata).ReferentialConstraints[0];
            bool flag = (object)this.WrappedOwner.EntityKey != null && !this.WrappedOwner.EntityKey.IsTemporary && this.IsDependentEndOfReferentialConstraint(true);
            ObjectStateManager objectStateManager = this.ObjectContext.ObjectStateManager;

            objectStateManager.TransactionManager.BeginForeignKeyUpdate(this);
            try
            {
                EntitySet entitySet1 = ((AssociationSet)this.RelationshipSet).AssociationSetEnds[this.ToEndMember.Name].EntitySet;
                StateManagerTypeMetadata managerTypeMetadata1 = objectStateManager.GetOrAddStateManagerTypeMetadata(principalEntity.IdentityType, entitySet1);
                EntitySet entitySet2 = ((AssociationSet)this.RelationshipSet).AssociationSetEnds[this.FromEndMember.Name].EntitySet;
                StateManagerTypeMetadata managerTypeMetadata2           = objectStateManager.GetOrAddStateManagerTypeMetadata(dependentEntity.IdentityType, entitySet2);
                ReadOnlyMetadataCollection <EdmProperty> fromProperties = referentialConstraint.FromProperties;
                int      count = fromProperties.Count;
                string[] array = (string[])null;
                object[] compositeKeyValues = (object[])null;
                if (count > 1)
                {
                    array = entitySet1.ElementType.KeyMemberNames;
                    compositeKeyValues = new object[count];
                }
                for (int index1 = 0; index1 < count; ++index1)
                {
                    int    olayerMemberName1 = managerTypeMetadata1.GetOrdinalforOLayerMemberName(fromProperties[index1].Name);
                    object obj = managerTypeMetadata1.Member(olayerMemberName1).GetValue(principalEntity.Entity);
                    int    olayerMemberName2       = managerTypeMetadata2.GetOrdinalforOLayerMemberName(referentialConstraint.ToProperties[index1].Name);
                    bool   changingForeignKeyValue = !ByValueEqualityComparer.Default.Equals(managerTypeMetadata2.Member(olayerMemberName2).GetValue(dependentEntity.Entity), obj);
                    if (forceChange || changingForeignKeyValue)
                    {
                        if (flag)
                        {
                            this.ValidateSettingRIConstraints(principalEntity, obj == null, changingForeignKeyValue);
                        }
                        if (changedFKs != null)
                        {
                            object x;
                            if (changedFKs.TryGetValue(olayerMemberName2, out x))
                            {
                                if (!ByValueEqualityComparer.Default.Equals(x, obj))
                                {
                                    throw new InvalidOperationException(Strings.Update_ReferentialConstraintIntegrityViolation);
                                }
                            }
                            else
                            {
                                changedFKs[olayerMemberName2] = obj;
                            }
                        }
                        dependentEntity.SetCurrentValue(dependentEntity.ObjectStateEntry, managerTypeMetadata2.Member(olayerMemberName2), -1, dependentEntity.Entity, obj);
                    }
                    if (count > 1)
                    {
                        int index2 = Array.IndexOf <string>(array, fromProperties[index1].Name);
                        compositeKeyValues[index2] = obj;
                    }
                    else
                    {
                        this.SetCachedForeignKey(obj == null ? (EntityKey)null : new EntityKey((EntitySetBase)entitySet1, obj), dependentEntity.ObjectStateEntry);
                    }
                }
                if (count > 1)
                {
                    this.SetCachedForeignKey(((IEnumerable <object>)compositeKeyValues).Any <object>((Func <object, bool>)(v => v == null)) ? (EntityKey)null : new EntityKey((EntitySetBase)entitySet1, compositeKeyValues), dependentEntity.ObjectStateEntry);
                }
                if (this.WrappedOwner.ObjectStateEntry == null)
                {
                    return;
                }
                objectStateManager.ForgetEntryWithConceptualNull(this.WrappedOwner.ObjectStateEntry, false);
            }
            finally
            {
                objectStateManager.TransactionManager.EndForeignKeyUpdate();
            }
        }