/// <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; } } } } }
/// <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); } } }
/// <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; } } }
/// <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); } }