Пример #1
0
        /// <summary>
        /// 把整个聚合对象的 Id 设置完整。
        /// </summary>
        /// <param name="oldEntity"></param>
        /// <param name="newEntity"></param>
        private static void MergeIdRecur(Entity oldEntity, Entity newEntity)
        {
            oldEntity.LoadProperty(Entity.IdProperty, newEntity.GetProperty(Entity.IdProperty));

            foreach (var field in oldEntity.GetLoadedChildren())
            {
                var listProperty = field.Property as IListProperty;
                if (listProperty != null)
                {
                    var oldChildren = field.Value as EntityList;
                    var newChildren = newEntity.GetLazyList(listProperty) as EntityList;

                    //两个集合应该是一样的数据、顺序?如果后期出现 bug,则修改此处的逻辑为查找到对应项再修改。
                    for (int i = 0, c = oldChildren.Count; i < c; i++)
                    {
                        MergeIdRecur(oldChildren[i], newChildren[i]);
                    }

                    //同步组合父对象 Id
                    oldChildren.SyncParentEntityId(oldEntity);

                    //同步 TreePId
                    if (oldChildren.SupportTree)
                    {
                        for (int i = 0, c = oldChildren.Count; i < c; i++)
                        {
                            var oldChild = oldChildren[i];
                            var newChild = newChildren[i];
                            oldChild.TreePId = newChild.TreePId;
                        }
                    }
                }
            }
        }
Пример #2
0
        /// <summary>
        /// 把指定实体的所有组合子实体都加载到内存中。(非递归)
        /// </summary>
        /// <param name="entity"></param>
        public void LoadAllChildren(Entity entity)
        {
            var childProperties = this.GetChildProperties();

            for (int i = 0, c = childProperties.Count; i < c; i++)
            {
                var childProperty = childProperties[i] as IListProperty;
                if (childProperty != null)
                {
                    //不论这个列表属性是否已经加载,都必须获取其所有的数据行,并标记为删除。
                    entity.GetLazyList(childProperty);
                }
            }
        }
Пример #3
0
        /// <summary>
        /// 删除所有组合子。
        ///
        /// 子类重写此方法来实现新的删除逻辑。
        /// 注意,此方法只会在指定了 <see cref="EnableDeletingChildrenInMemory"/> 时,才会调用。
        /// </summary>
        protected virtual void DeleteChildren(Entity entity)
        {
            foreach (var mp in _repository.EntityMeta.ManagedProperties.GetNonReadOnlyCompiledProperties())
            {
                var listProperty = mp as IListProperty;
                if (listProperty != null && listProperty.HasManyType == HasManyType.Composition)
                {
                    //不论这个列表属性是否已经加载,都必须获取其所有的数据行,并标记为删除。
                    var list = entity.GetLazyList(listProperty);
                    if (list.Count > 0)
                    {
                        list.Clear();

                        //删除所有子。
                        SaveRecur(list, entity);
                    }
                }
            }
        }
        private void DeepSearchRecur_Instance(Entity entity)
        {
            var values = entity.GetNonDefaultPropertyValues();

            foreach (var value in values)
            {
                var mp = value.Property as IProperty;
                switch (mp.Category)
                {
                case PropertyCategory.ReferenceEntity:
                    if (mp.GetMeta(entity).Serializable)
                    {
                        var refEntity = entity.GetRefEntity(mp as IRefEntityProperty);
                        AddEntityType(refEntity.GetType());
                        DeepSearchRecur_Instance(refEntity);
                    }
                    break;

                case PropertyCategory.List:
                    if (mp.GetMeta(entity).Serializable)
                    {
                        var list = entity.GetLazyList(mp as IListProperty);
                        for (int i = 0, c = list.Count; i < c; i++)
                        {
                            var child = list[i];
                            if (i == 0)
                            {
                                AddEntityType(child.GetType());
                            }
                            DeepSearchRecur_Instance(child);
                        }
                    }
                    break;

                default:
                    break;
                }
            }
        }
Пример #5
0
        /// <summary>
        /// 复制目标对象的所有字段。
        /// 子类重写此方法额外做以下几件事:
        /// 1. 如果有自定义字段,请在此方法中进行值拷贝。
        /// 2. 如果有延迟加载的外键引用对象 ILazyEntityRef,请调用它的 Clone 方法进行拷贝。
        /// 3. 如果使用了快速字段 FastField 来进行属性的缓存,请在基类完成 Clone 后,调用本类的 ResetFastField 方法来清空缓存。
        /// </summary>
        /// <param name="source">The source.</param>
        /// <param name="options">The options.</param>
        /// <exception cref="System.ArgumentNullException">source
        /// or
        /// options</exception>
        protected virtual void CloneCore(Entity source, CloneOptions options)
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }
            if (options == null)
            {
                throw new ArgumentNullException("options");
            }

            var grabChildren  = options.HasAction(CloneActions.GrabChildren);
            var childrenRecur = options.HasAction(CloneActions.ChildrenRecur);
            var copyId        = options.HasAction(CloneActions.IdProperty);

            var ingoreList = options.RetrieveIgnoreListOnce();

            //如果需要拷贝id,则应该先拷贝id,并立刻清空id的缓存。
            //注意:
            //由于 IdProperty 在 AllProperties 中的位置并不是第一个。所以会出现拷贝其它属性时,再次访问本ID导致缓存重建。
            //所以这里需要单独对 Id 进行一次拷贝。
            if (copyId)
            {
                this.CopyProperty(source, IdProperty, options);
            }

            //复制目标对象的所有托管属性。
            var allProperties = this.PropertiesContainer.GetAvailableProperties();

            for (int i = 0, c = allProperties.Count; i < c; i++)
            {
                var property = allProperties[i];
                if (property.IsReadOnly)
                {
                    continue;
                }
                //var propertyMeta = property.GetMeta(this) as IPropertyMetadata;

                //过滤一些不需要拷贝的属性
                if (property == IdProperty && !copyId)
                {
                    continue;
                }
                if (ingoreList != null && ingoreList.Contains(property))
                {
                    continue;
                }
                //已经更改了GetLazyChildren方法,不再考虑null值的拷贝。
                ////如果目标不存在这个值时,不需要也不能进行拷贝,否则会为懒加载属性的加载null值。
                //if (!target.FieldManager.FieldExists(propertyInfo)) continue;

                if (property is IListProperty)
                {
                    var listProperty = property as IListProperty;
                    if (childrenRecur)
                    {
                        var sourceList = source.GetLazyList(listProperty);
                        var targetList = this.GetLazyList(listProperty);
                        targetList.Clone(sourceList, options);

                        var isComposition = targetList.HasManyType == HasManyType.Composition;
                        if (isComposition)
                        {
                            targetList.SetParentEntity(this);
                        }
                    }
                    else if (grabChildren)
                    {
                        var children = source.GetProperty(property) as EntityList;
                        this.LoadProperty(property, children);
                        if (children == null)
                        {
                            return;
                        }

                        var isComposition = children.HasManyType == HasManyType.Composition;
                        if (isComposition)
                        {
                            children.SetParentEntity(this);
                        }
                    }
                }
                else
                {
                    this.CopyProperty(source, property, options);
                }
            }

            options.NotifyCloned(source, this);

            if (this.SupportTree)
            {
                this.OnTreeItemCloned(source, options);
            }
        }