コード例 #1
0
 public void SetCurrentValue(
     EntityEntry entry,
     StateManagerMemberMetadata member,
     int ordinal,
     object target,
     object value)
 {
     if (object.ReferenceEquals(target, entry.Entity))
     {
         ((IEntityChangeTracker)entry).EntityMemberChanging(member.CLayerName);
         member.SetValue(target, value);
         ((IEntityChangeTracker)entry).EntityMemberChanged(member.CLayerName);
         if (!member.IsComplex)
         {
             return;
         }
         entry.UpdateComplexObjectSnapshot(member, target, ordinal, value);
     }
     else
     {
         member.SetValue(target, value);
         if (entry.State == EntityState.Added)
         {
             return;
         }
         entry.DetectChangesInProperties(true);
     }
 }
コード例 #2
0
 public void SetCurrentValue(
     EntityEntry entry,
     StateManagerMemberMetadata member,
     int ordinal,
     object target,
     object value)
 {
 }
コード例 #3
0
 public override void SetCurrentValue(
     EntityEntry entry,
     StateManagerMemberMetadata member,
     int ordinal,
     object target,
     object value)
 {
     this._changeTrackingStrategy.SetCurrentValue(entry, member, ordinal, target, value);
 }
 public override void SetCurrentValue(
     EntityEntry entry,
     StateManagerMemberMetadata member,
     int ordinal,
     object target,
     object value)
 {
     member.SetValue(target, value);
 }
コード例 #5
0
        // See IChangeTrackingStrategy documentation
        public void SetCurrentValue(EntityEntry entry, StateManagerMemberMetadata member, int ordinal, object target, object value)
        {
            // If the target is the entity, then this is a change to a member on the entity itself rather than
            // a change to some complex type property defined on the entity.  In this case we can use the change tracking
            // API in the normal way.
            if (ReferenceEquals(target, entry.Entity))
            {
                // equivalent of EntityObject.ReportPropertyChanging()
                ((IEntityChangeTracker)entry).EntityMemberChanging(member.CLayerName);
                member.SetValue(target, value);
                // equivalent of EntityObject.ReportPropertyChanged()
                ((IEntityChangeTracker)entry).EntityMemberChanged(member.CLayerName);

                if (member.IsComplex)
                {
                    // This is required because the OSE contains a separate cache of user objects for
                    // complex objects such that original values can be looked up correctly.
                    entry.UpdateComplexObjectSnapshot(member, target, ordinal, value);
                }
            }
            else
            {
                // Must be a complex type.  We would like to do this:
                // ((IEntityChangeTracker)entry).EntityComplexMemberChanging(topLevelMember.CLayerName, target, member.CLayerName);
                // ((IEntityChangeTracker)entry).EntityComplexMemberChanged(topLevelMember.CLayerName, target, member.CLayerName);
                //
                // However, we have no way of getting the topLevelMember.CLayerName.  This is because the value record does not
                // contain any reference to its parent.  (In non-POCO, ComplexObject takes care of this.)
                // Therefore, in this case we are going to just call a localized DetectChanges to make sure that changes in the
                // complex types are found.
                //
                // Note that this case only happens when the entity is POCO and complex types are set through the CurrentValues
                // object.  This is probably not a very common pattern.
                member.SetValue(target, value);
                if (entry.State
                    != EntityState.Added)
                {
                    // Entry is not Detached - checked in ValidateState() in EntityEntry.SetCurrentEntityValue
                    entry.DetectChangesInProperties(true);
                }
            }
        }
コード例 #6
0
        // See IChangeTrackingStrategy documentation
        public void SetCurrentValue(EntityEntry entry, StateManagerMemberMetadata member, int ordinal, object target, object value)
        {
            // If the target is the entity, then this is a change to a member on the entity itself rather than
            // a change to some complex type property defined on the entity.  In this case we can use the change tracking
            // API in the normal way.
            if (ReferenceEquals(target, entry.Entity))
            {
                // equivalent of EntityObject.ReportPropertyChanging()
                ((IEntityChangeTracker)entry).EntityMemberChanging(member.CLayerName);
                member.SetValue(target, value);
                // equivalent of EntityObject.ReportPropertyChanged()
                ((IEntityChangeTracker)entry).EntityMemberChanged(member.CLayerName);

                if (member.IsComplex)
                {
                    // This is required because the OSE contains a separate cache of user objects for
                    // complex objects such that original values can be looked up correctly.
                    entry.UpdateComplexObjectSnapshot(member, target, ordinal, value);
                }
            }
            else
            {
                // Must be a complex type.  We would like to do this:
                // ((IEntityChangeTracker)entry).EntityComplexMemberChanging(topLevelMember.CLayerName, target, member.CLayerName);
                // ((IEntityChangeTracker)entry).EntityComplexMemberChanged(topLevelMember.CLayerName, target, member.CLayerName);
                //
                // However, we have no way of getting the topLevelMember.CLayerName.  This is because the value record does not
                // contain any reference to its parent.  (In non-POCO, ComplexObject takes care of this.)
                // Therefore, in this case we are going to just call a localized DetectChanges to make sure that changes in the
                // complex types are found.
                //
                // Note that this case only happens when the entity is POCO and complex types are set through the CurrentValues
                // object.  This is probably not a very common pattern.
                member.SetValue(target, value);
                if (entry.State
                    != EntityState.Added)
                {
                    // Entry is not Detached - checked in ValidateState() in EntityEntry.SetCurrentEntityValue
                    entry.DetectChangesInProperties(true);
                }
            }
        }
コード例 #7
0
 public StateManagerValue(StateManagerMemberMetadata metadata, object instance, object value)
 {
     this.MemberMetadata = metadata;
     this.UserObject     = instance;
     this.OriginalValue  = value;
 }
コード例 #8
0
 // See IChangeTrackingStrategy documentation
 public void SetCurrentValue(EntityEntry entry, StateManagerMemberMetadata member, int ordinal, object target, object value)
 {
     member.SetValue(target, value);
 }
コード例 #9
0
 public StateManagerValue(StateManagerMemberMetadata metadata, object instance, object value)
 {
     MemberMetadata = metadata;
     UserObject = instance;
     OriginalValue = value;
 }
コード例 #10
0
 public void SetCurrentValue(EntityEntry entry, StateManagerMemberMetadata member, int ordinal, object target, object value)
 {
     Debug.Fail("Cannot set a value onto a null entity.");
 }
コード例 #11
0
        /// <summary>
        /// Attempts to null all FKs associated with the dependent end of this relationship on this entity.
        /// This may result in setting conceptual nulls if the FK is not nullable.
        /// </summary>
        internal void NullAllForeignKeys()
        {
            Debug.Assert(ObjectContext != null, "Nulling FKs only works when attached.");
            Debug.Assert(IsForeignKey, "Cannot null FKs for independent associations.");

            ObjectStateManager stateManager = ObjectContext.ObjectStateManager;
            EntityEntry        entry        = WrappedOwner.ObjectStateEntry;
            TransactionManager transManager = stateManager.TransactionManager;

            if (!transManager.IsGraphUpdate && !transManager.IsAttachTracking && !transManager.IsRelatedEndAdd)
            {
                ReferentialConstraint constraint = ((AssociationType)RelationMetadata).ReferentialConstraints.Single();
                if (TargetRoleName == constraint.FromRole.Name) // Only do this on the dependent end
                {
                    if (transManager.IsDetaching)
                    {
                        // If the principal is being detached, then the dependent must be added back to the
                        // dangling keys index.
                        // Perf note: The dependent currently gets added when it is being detached and is then
                        // removed again later in the process.  The code could be optimized to prevent this.
                        Debug.Assert(entry != null, "State entry must exist while detaching.");
                        EntityKey foreignKey = ForeignKeyFactory.CreateKeyFromForeignKeyValues(entry, this);
                        if (foreignKey != null)
                        {
                            stateManager.AddEntryContainingForeignKeyToIndex(foreignKey, entry);
                        }
                    }
                    else if (!ReferenceEquals(stateManager.EntityInvokingFKSetter, WrappedOwner.Entity) && !transManager.IsForeignKeyUpdate)
                    {
                        transManager.BeginForeignKeyUpdate(this);
                        try
                        {
                            bool      unableToNull        = true;
                            bool      canSetModifiedProps = entry != null && (entry.State == EntityState.Modified || entry.State == EntityState.Unchanged);
                            EntitySet dependentEntitySet  = ((AssociationSet)RelationshipSet).AssociationSetEnds[FromEndProperty.Name].EntitySet;
                            StateManagerTypeMetadata dependentTypeMetadata = stateManager.GetOrAddStateManagerTypeMetadata(WrappedOwner.IdentityType, dependentEntitySet);

                            for (int i = 0; i < constraint.FromProperties.Count; i++)
                            {
                                string propertyName               = constraint.ToProperties[i].Name;
                                int    dependentOrdinal           = dependentTypeMetadata.GetOrdinalforOLayerMemberName(propertyName);
                                StateManagerMemberMetadata member = dependentTypeMetadata.Member(dependentOrdinal);

                                // This is a check for nullability in o-space. However, o-space nullability is not the
                                // same as nullability of the underlying type. In particular, one difference is that when
                                // attribute-based mapping is used then a property can be marked as not nullable in o-space
                                // even when the underlying CLR type is nullable. For such a case, we treat the property
                                // as if it were not nullable (since that's what we have shipped) even though we could
                                // technically set it to null.
                                if (member.ClrMetadata.Nullable)
                                {
                                    // Only set the value to null if it is not already null.
                                    if (member.GetValue(WrappedOwner.Entity) != null)
                                    {
                                        WrappedOwner.SetCurrentValue(
                                            WrappedOwner.ObjectStateEntry,
                                            dependentTypeMetadata.Member(dependentOrdinal),
                                            -1,
                                            WrappedOwner.Entity,
                                            null);
                                    }
                                    else
                                    {
                                        // Given that the current value is null, this next check confirms that the original
                                        // value is also null.  If it isn't, then we must make sure that the entity is marked
                                        // as modified.
                                        // This case can happen because fixup in the entity can set the FK to null while processing
                                        // a RelatedEnd operation.  This will be detected by DetectChanges, but when performing
                                        // RelatedEnd operations the user is not required to call DetectChanges.
                                        if (canSetModifiedProps && WrappedOwner.ObjectStateEntry.OriginalValues.GetValue(dependentOrdinal) != null)
                                        {
                                            entry.SetModifiedProperty(propertyName);
                                        }
                                    }
                                    unableToNull = false;
                                }
                                else if (canSetModifiedProps)
                                {
                                    entry.SetModifiedProperty(propertyName);
                                }
                            }
                            if (unableToNull)
                            {
                                // We were unable to null out the FK because all FK properties were non-nullable.
                                // We need to keep track of this state so that we treat the FK as null even though
                                // we were not able to null it.  This prevents the FK from being used for fixup and
                                // also causes an exception to be thrown if an attempt is made to commit in this state.

                                //We should only set a conceptual null if the entity is tracked
                                if (entry != null)
                                {
                                    //The CachedForeignKey may be null if we are putting
                                    //back a Conceptual Null as part of roll back
                                    EntityKey realKey = CachedForeignKey;
                                    if (realKey == null)
                                    {
                                        realKey = ForeignKeyFactory.CreateKeyFromForeignKeyValues(entry, this);
                                    }

                                    // Note that the realKey can still be null here for a situation where the key is marked not nullable
                                    // in o-space and yet the underlying type is nullable and the entity has been added or attached with a null
                                    // value for the property. This will cause SaveChanges to throw unless the entity is marked
                                    // as deleted before SaveChanges is called, in which case we don't want to set a conceptual
                                    // null here as the call might very well succeed in the database since, unless the FK is
                                    // a concurrency token, the value we have for it is not used at all for the delete.
                                    if (realKey != null)
                                    {
                                        SetCachedForeignKey(ForeignKeyFactory.CreateConceptualNullKey(realKey), entry);
                                        stateManager.RememberEntryWithConceptualNull(entry);
                                    }
                                }
                            }
                            else
                            {
                                SetCachedForeignKey(null, entry);
                            }
                        }
                        finally
                        {
                            transManager.EndForeignKeyUpdate();
                        }
                    }
                }
            }
        }
コード例 #12
0
 internal StateManagerValue(StateManagerMemberMetadata metadata, object instance, object value)
 {
     memberMetadata = metadata;
     userObject = instance;
     originalValue = value;
 }
コード例 #13
0
 public void SetCurrentValue(EntityEntry entry, StateManagerMemberMetadata member, int ordinal, object target, object value)
 {
     Debug.Fail("Cannot set a value onto a null entity.");
 }
コード例 #14
0
        internal void NullAllForeignKeys()
        {
            ObjectStateManager objectStateManager = this.ObjectContext.ObjectStateManager;
            EntityEntry        objectStateEntry   = this.WrappedOwner.ObjectStateEntry;
            TransactionManager transactionManager = objectStateManager.TransactionManager;

            if (transactionManager.IsGraphUpdate || transactionManager.IsAttachTracking || transactionManager.IsRelatedEndAdd)
            {
                return;
            }
            ReferentialConstraint referentialConstraint = ((AssociationType)this.RelationMetadata).ReferentialConstraints.Single <ReferentialConstraint>();

            if (!(this.TargetRoleName == referentialConstraint.FromRole.Name))
            {
                return;
            }
            if (transactionManager.IsDetaching)
            {
                EntityKey foreignKeyValues = ForeignKeyFactory.CreateKeyFromForeignKeyValues(objectStateEntry, (RelatedEnd)this);
                if (!(foreignKeyValues != (EntityKey)null))
                {
                    return;
                }
                objectStateManager.AddEntryContainingForeignKeyToIndex(this, foreignKeyValues, objectStateEntry);
            }
            else
            {
                if (object.ReferenceEquals(objectStateManager.EntityInvokingFKSetter, this.WrappedOwner.Entity) || transactionManager.IsForeignKeyUpdate)
                {
                    return;
                }
                transactionManager.BeginForeignKeyUpdate(this);
                try
                {
                    bool      flag1     = true;
                    bool      flag2     = objectStateEntry != null && (objectStateEntry.State == EntityState.Modified || objectStateEntry.State == EntityState.Unchanged);
                    EntitySet entitySet = ((AssociationSet)this.RelationshipSet).AssociationSetEnds[this.FromEndMember.Name].EntitySet;
                    StateManagerTypeMetadata managerTypeMetadata = objectStateManager.GetOrAddStateManagerTypeMetadata(this.WrappedOwner.IdentityType, entitySet);
                    for (int index = 0; index < referentialConstraint.FromProperties.Count; ++index)
                    {
                        string name             = referentialConstraint.ToProperties[index].Name;
                        int    olayerMemberName = managerTypeMetadata.GetOrdinalforOLayerMemberName(name);
                        StateManagerMemberMetadata managerMemberMetadata = managerTypeMetadata.Member(olayerMemberName);
                        if (managerMemberMetadata.ClrMetadata.Nullable)
                        {
                            if (managerMemberMetadata.GetValue(this.WrappedOwner.Entity) != null)
                            {
                                this.WrappedOwner.SetCurrentValue(this.WrappedOwner.ObjectStateEntry, managerTypeMetadata.Member(olayerMemberName), -1, this.WrappedOwner.Entity, (object)null);
                            }
                            else if (flag2 && this.WrappedOwner.ObjectStateEntry.OriginalValues.GetValue(olayerMemberName) != null)
                            {
                                objectStateEntry.SetModifiedProperty(name);
                            }
                            flag1 = false;
                        }
                        else if (flag2)
                        {
                            objectStateEntry.SetModifiedProperty(name);
                        }
                    }
                    if (flag1)
                    {
                        if (objectStateEntry == null)
                        {
                            return;
                        }
                        EntityKey originalKey = this.CachedForeignKey;
                        if (originalKey == (EntityKey)null)
                        {
                            originalKey = ForeignKeyFactory.CreateKeyFromForeignKeyValues(objectStateEntry, (RelatedEnd)this);
                        }
                        if (!(originalKey != (EntityKey)null))
                        {
                            return;
                        }
                        this.SetCachedForeignKey(ForeignKeyFactory.CreateConceptualNullKey(originalKey), objectStateEntry);
                        objectStateManager.RememberEntryWithConceptualNull(objectStateEntry);
                    }
                    else
                    {
                        this.SetCachedForeignKey((EntityKey)null, objectStateEntry);
                    }
                }
                finally
                {
                    transactionManager.EndForeignKeyUpdate();
                }
            }
        }
コード例 #15
0
 internal StateManagerValue(StateManagerMemberMetadata metadata, object instance, object value)
 {
     memberMetadata = metadata;
     userObject     = instance;
     originalValue  = value;
 }