protected override void VisitEntityRef(IEntityRef entityRef, Entity parent, MetaMember member)
            {
                if (member.IsComposition)
                {
                    Entity child = null;
                    if (entityRef == null)
                    {
                        // If the EntityRef hasn't been accessed before, it might
                        // not be initialized yet. In this case we need to access
                        // the property directly to force it to load.
                        child = (Entity)member.GetValue(parent);
                    }
                    else
                    {
                        child = entityRef.Entity;
                    }

                    if (child != null)
                    {
                        bool lastIsChild = this._isChild;
                        this._isChild = true;

                        this.Visit(child);

                        this._isChild = lastIsChild;
                    }
                }
            }
示例#2
0
        /// <summary>
        /// When a complex property on this instance changes, this method performs
        /// the necessary attach/detach operations for the new instance.
        /// </summary>
        /// <param name="metaMember">The complex member.</param>
        private void AttachComplexObjectInstance(MetaMember metaMember)
        {
            // First check if the parent has an existing instance attached for this
            // property and detach if necessary.
            string        memberName   = metaMember.Member.Name;
            ComplexObject prevInstance = null;

            if (this.TrackedInstances.TryGetValue(memberName, out prevInstance))
            {
                prevInstance.Detach();
                this.TrackedInstances.Remove(memberName);
            }

            ComplexObject newInstance = (ComplexObject)metaMember.GetValue(this);

            if (newInstance != null)
            {
                // Attach to the new instance
                newInstance.Attach(this, memberName, this.OnDataMemberChanging, this.OnDataMemberChanged, this.OnMemberValidationChanged);
                this.TrackedInstances[memberName] = newInstance;

                // If the instance has validation errors, we need to sync them into our parent. This
                // needs to be done as a merge operation, since the parent may already have property
                // level errors for this member that must be retained.
                if (newInstance.HasValidationErrors)
                {
                    foreach (ValidationResult error in ValidationUtilities.ApplyMemberPath(newInstance.ValidationErrors, memberName))
                    {
                        this.ValidationResultCollection.Add(error);
                    }
                }
            }
        }
示例#3
0
        /// <summary>
        /// Resolves the conflict by updating the entity's original state with the current store state.
        /// If the entity has a timestamp concurrency member, the current store timestamp will be copied
        /// to the entity instance. <see cref="Entity.EntityConflict"/> is also cleared on <see cref="CurrentEntity"/>.
        /// </summary>
        /// <exception cref="InvalidOperationException">Thrown if <see cref="Resolve"/> is called when <see cref="IsDeleted"/>
        /// is <c>true</c>.</exception>
        public void Resolve()
        {
            if (this.CurrentEntity.EntityConflict == null)
            {
                // the conflict has already been resolved
                return;
            }

            if (this.IsDeleted)
            {
                throw new InvalidOperationException(Resource.EntityConflict_CannotResolveDeleteConflict);
            }

            // update the entity's original state
            this.CurrentEntity.UpdateOriginalValues(this.StoreEntity);

            // if the entity has a concurrency timestamp member, we must sync that
            // timestamp value into the current entity
            MetaMember versionMember = this._currentEntity.MetaType.VersionMember;

            if (versionMember != null)
            {
                object storeValue = versionMember.GetValue(this._storeEntity);

                // since Timestamp values are readonly, we must use ApplyState to set the value
                this._currentEntity.ApplyState(new Dictionary <string, object> {
                    { versionMember.Name, storeValue }
                });
            }

            // clear the conflict now that it is resolved
            this.CurrentEntity.EntityConflict = null;
        }
示例#4
0
        /// <summary>
        /// Determines whether the specified property has changed value.
        /// </summary>
        /// <param name="o">The parent of the property.</param>
        /// <param name="originalValues">The original values for the modified parent instance.</param>
        /// <param name="member">The property to check.</param>
        /// <returns>True if the property has changed, false otherwise.</returns>
        internal static bool PropertyHasChanged(object o, IDictionary <string, object> originalValues, MetaMember member)
        {
            if (originalValues == null)
            {
                return(false);
            }

            object currentValue = member.GetValue(o);
            object originalValue;

            if (!originalValues.TryGetValue(member.Name, out originalValue))
            {
                throw new InvalidOperationException(
                          string.Format(CultureInfo.CurrentCulture, Resource.Entity_Property_NotChangeTracked, member.Name, o.GetType()));
            }

            if (!object.Equals(currentValue, originalValue))
            {
                return(true);
            }

            return(false);
        }
示例#5
0
        /// <summary>
        /// When a complex property on this instance changes, this method performs
        /// the necessary attach/detach operations for the new instance.
        /// </summary>
        /// <param name="metaMember">The complex member.</param>
        private void AttachComplexObjectInstance(MetaMember metaMember)
        {
            // First check if the parent has an existing instance attached for this
            // property and detach if necessary.
            string memberName = metaMember.Member.Name;
            ComplexObject prevInstance = null;
            if (this.TrackedInstances.TryGetValue(memberName, out prevInstance))
            {
                prevInstance.Detach();
                this.TrackedInstances.Remove(memberName);
            }

            ComplexObject newInstance = (ComplexObject)metaMember.GetValue(this);
            if (newInstance != null)
            {
                // Attach to the new instance
                newInstance.Attach(this, memberName, this.OnDataMemberChanging, this.OnDataMemberChanged, this.OnMemberValidationChanged);
                this.TrackedInstances[memberName] = newInstance;

                // If the instance has validation errors, we need to sync them into our parent. This
                // needs to be done as a merge operation, since the parent may already have property
                // level errors for this member that must be retained.
                if (newInstance.HasValidationErrors)
                {
                    foreach (ValidationResult error in ValidationUtilities.ApplyMemberPath(newInstance.ValidationErrors, memberName))
                    {
                        this.ValidationResultCollection.Add(error);
                    }
                }
            }
        }