private void DeserializeList(Entity entity, IListProperty listProperty, JArray jArray) { var list = entity.GetLazyList(listProperty); var isNew = entity.PersistenceStatus == PersistenceStatus.New; if (isNew) { foreach (JObject jChild in jArray) { var child = list.GetRepository().New(); DeserializeProperties(jChild, child); list.Add(child); } } else { //这里会发起查询,获取当前在数据库中的实体。 for (int i = 0, c = jArray.Count; i < c; i++) { var jChild = jArray[i] as JObject; var child = FindOrCreate(list, jChild); DeserializeProperties(jChild, child); } } }
/// <summary> /// Adds an item to the list /// /// * If the list has no type the type will be infered from the given object /// * If the list has no type and `null` is added the type will be set as `object` /// </summary> /// <param name="obj"></param> /// <exception cref="Exception">If the given object is not assignable to the list type</exception> public void Add(object obj) { if (null == m_Items) { // Special case when adding an element and we have no items // Dynamically create the list and properties to be strongly typed. We must use activator in this situation var type = obj?.GetType() ?? typeof(object); m_Items = Activator.CreateInstance(typeof(List <>).MakeGenericType(type)); m_ItemsProperty = CreateItemsProperty(type); m_PropertyBag.AddProperty(m_ItemsProperty); } if (obj is UTinyObject) { // Special case for tiny object. We DON'T want to retain the given instance. // Instead we create a new object and deep copy the values in. This way the object // Will propegate version changes to this list var v = new UTinyObject(m_Registry, m_Type, this); v.CopyFrom((UTinyObject)obj); var typedList = (IListProperty <UTinyList, UTinyObject>)m_ItemsProperty; typedList.Add(this, v); } else { try { var converted = Convert(obj, m_ItemsProperty.ItemType); m_ItemsProperty.AddObject(this, converted); } catch (Exception e) { throw new Exception($"UTinyList.Add Type mismatch expected instance of Type=[{m_ItemsProperty.ItemType}] received Type=[{obj?.GetType()}]", e); } } }
private static void DeserializeList(Entity entity, IListProperty listProperty, JArray jArray) { var isNew = entity.PersistenceStatus == PersistenceStatus.New; if (isNew) { var list = entity.GetLazyList(listProperty); foreach (JObject jChild in jArray) { var child = list.GetRepository().New(); DeserializeProperties(jChild, child); list.Add(child); } } else { //这里会发起查询,获取当前在数据库中的实体。 var list = entity.GetLazyList(listProperty); foreach (JObject jChild in jArray) { Entity child = null; JToken jId = null; if (jChild.TryGetValue(Entity.IdProperty.Name, StringComparison.OrdinalIgnoreCase, out jId)) { child = list.Find((jId as JValue).Value); } if (child == null) { child = list.GetRepository().New(); list.Add(child); } DeserializeProperties(jChild, child); } } }
public static void BuildCollectionProperty(IListProperty property, TypeBuilder type, Dictionary <IBusinessObjectBase, TypeBuilder> definedTypes) { var ptype = typeof(IList <>).MakeGenericType(property.PropertyType.FindType(definedTypes)); var propertyInfo = type.DefineProperty(property.Name, PropertyAttributes.RTSpecialName, ptype, Type.EmptyTypes); if (property.ReadOnly) { propertyInfo.ReadOnly(); } if (!string.IsNullOrEmpty(property.Caption)) { propertyInfo.ModelDefault("Caption", property.Caption); } if (property.IsAggreagte) { propertyInfo.Aggregate(); } var attr = MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.VtableLayoutMask | MethodAttributes.Abstract | MethodAttributes.SpecialName; // System.Reflection. //var setattr = MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.VtableLayoutMask | MethodAttributes.Abstract | MethodAttributes.SpecialName; propertyInfo.SetGetMethod(type.DefineMethod("get_" + property.Name, attr, ptype, Type.EmptyTypes)); //var set = type.DefineMethod("set_" + property.Name, setattr, typeof(void), new Type[] { ptype }); //set.DefineParameter(1, ParameterAttributes.None, "value"); //propertyInfo.SetSetMethod(set); ReferencePropertyLogic.BuildFilterOption(property, propertyInfo); }
/// <summary> /// 通过一个聚合子实体属性构造一个界面块 /// </summary> /// <param name="label"></param> /// <param name="childrenProperty"></param> public ChildBlock(string label, IListProperty childrenProperty) { if (label == null) throw new ArgumentNullException("label"); if (childrenProperty == null) throw new ArgumentNullException("childrenProperty"); this.Label = label; this.ChildrenProperty = childrenProperty; }
/// <summary> /// 通过一个聚合子实体属性构造一个界面块 /// 本构造函数直接使用该属性对应实体的默认视图中的名称作用本子块的 Label /// </summary> /// <param name="childrenProperty"></param> public ChildBlock(IListProperty childrenProperty) { if (childrenProperty == null) { throw new ArgumentNullException("childrenProperty"); } this.ChildrenProperty = childrenProperty; }
public void CopyTo(IListProperty dest) { ListProperty <Type> list = (ListProperty <Type>)dest; list.Clear(); for (int i = 0; i < this.list.Count; i++) { list.Add(this.list[i]); } }
/// <summary> /// 通过一个聚合子实体属性构造一个界面块 /// </summary> /// <param name="label"></param> /// <param name="childrenProperty"></param> public ChildBlock(string label, IListProperty childrenProperty) { if (label == null) { throw new ArgumentNullException("label"); } if (childrenProperty == null) { throw new ArgumentNullException("childrenProperty"); } this.Label = label; this.ChildrenProperty = childrenProperty; }
private void DeserializeList(Entity entity, IListProperty listProperty, JArray jArray) { //构造 List 对象 EntityList list = null; if (entity.FieldExists(listProperty) || entity.IsNew) { list = entity.GetLazyList(listProperty); } else { if (_creationMode == UpdatedEntityCreationMode.RequeryFromRepository) { list = entity.GetLazyList(listProperty); } else { var listRepository = RepositoryFactoryHost.Factory.FindByEntity(listProperty.ListEntityType); list = listRepository.NewList(); entity.LoadProperty(listProperty, list); } } //反序列化其中的每一个元素。 if (entity.IsNew) { var listRepository = list.GetRepository(); foreach (JObject jChild in jArray) { var child = listRepository.New(); DeserializeProperties(jChild, child); list.Add(child); } } else { //这里会发起查询,获取当前在数据库中的实体。 for (int i = 0, c = jArray.Count; i < c; i++) { var jChild = jArray[i] as JObject; var child = FindOrCreate(list, jChild); DeserializeProperties(jChild, child); } } }
/// <summary> /// 对实体列表中每一个实体都贪婪加载出它的所有子实体。 /// </summary> /// <param name="list"></param> /// <param name="listProperty">贪婪加载的列表子属性。</param> /// <param name="eagerLoadProperties">所有还需要贪婪加载的属性。</param> private void EagerLoadChildren(EntityList list, IListProperty listProperty, List <ConcreteProperty> eagerLoadProperties) { //查询一个大的实体集合,包含列表中所有实体所需要的所有子实体。 var idList = new List <object>(10); list.EachNode(e => { idList.Add(e.Id); return(false); }); if (idList.Count > 0) { var targetRepo = RepositoryFactoryHost.Factory.FindByEntity(listProperty.ListEntityType); var allChildren = targetRepo.GetByParentIdList(idList.ToArray(), PagingInfo.Empty); //继续递归加载它的贪婪属性。 this.EagerLoad(allChildren, eagerLoadProperties); //把大的实体集合,根据父实体 Id,分拆到每一个父实体的子集合中。 var parentProperty = targetRepo.FindParentPropertyInfo(true).ManagedProperty as IRefProperty; var parentIdProperty = parentProperty.RefIdProperty; list.EachNode(parent => { var children = targetRepo.NewList(); foreach (var child in allChildren) { var pId = child.GetRefId(parentIdProperty); if (object.Equals(pId, parent.Id)) { children.Add(child); } } children.SetParentEntity(parent); parent.LoadProperty(listProperty, children); return(false); }); } }
/// <summary> /// 查找本实体对应的列表属性 /// /// 以下情况下返回 null: /// * 这是一个根对象的集合。 /// * 这是一个子对象的集合,但是这个集合不在根对象聚合树中。(没有 this.Parent 属性。) /// </summary> /// <returns></returns> private IListProperty FindListProperty() { if (this._listProperty == null) { var parentEntity = this.Parent; if (parentEntity != null) { var enumerator = parentEntity.GetLoadedChildren(); while (enumerator.MoveNext()) { var current = enumerator.Current; if (current.Value == this) { _listProperty = current.Property as IListProperty; break; } } } } return(this._listProperty); }
/// <summary> /// 执行懒加载操作。 /// </summary> /// <param name="listProperty">The list property.</param> /// <returns></returns> private EntityList LoadLazyList(IListProperty listProperty) { EntityList data = null; if (this.FieldExists(listProperty)) { data = this.GetProperty(listProperty) as EntityList; if (data != null) { return(data); } } if (this.IsNew) { var listRepository = RepositoryFactoryHost.Factory.FindByEntity(listProperty.ListEntityType); data = listRepository.NewList(); } else { var meta = listProperty.GetMeta(this) as IListPropertyMetadata; var dataProvider = meta.DataProvider; if (dataProvider != null) { data = dataProvider(this); } else { var listRepository = RepositoryFactoryHost.Factory.FindByEntity(listProperty.ListEntityType) as IRepositoryInternal; data = listRepository.GetLazyListByParent(this); data.SetParentEntity(this); } } this.LoadProperty(listProperty, data); return(data); }
public void Refresh(UTinyList defaultValue = null, bool skipTypeCheck = false) { var type = Type.Dereference(m_Registry); if (null == type) { return; } // Force the type to be refreshed if (!skipTypeCheck) { type.Refresh(); } if (m_CurrentTypeVersion == type.Version) { return; } // Migrate the values m_Items = MigrateListValue(m_Registry, this, m_Items as IList, type); // Rebuild the default value property if (null != m_ItemsProperty) { m_PropertyBag.RemoveProperty(m_ItemsProperty); } m_ItemsProperty = CreateItemsProperty(type); if (null != m_ItemsProperty) { m_PropertyBag.AddProperty(m_ItemsProperty); } m_CurrentTypeVersion = type.Version; }
protected bool BeginList(IPropertyContainer container, IListProperty property) { CurrentListProperty = property; if (ShouldHide(property)) { return(false); } PushEnabledState(); GUI.enabled &= !IsReadOnly(property); if (HasHeader(property)) { DrawHeader(property); } if (CanDrawAsList(property)) { if (Targets.Count > 1) { EditorGUILayout.HelpBox($"{UTinyConstants.ApplicationName}: Editing an array with multiple targets is not supported.", MessageType.Info); return(false); } // [MP] @HACK: Special case for UTinyList where the property name doesn't match the field name. var list = container as UTinyList; if (list != null) { EditorGUILayout.LabelField(list.Name); } else { EditorGUILayout.LabelField(ConstructLabel(property)); } EditorGUILayout.BeginHorizontal(); GUILayout.Space(EditorGUI.indentLevel * 15.0f); EditorGUILayout.BeginVertical(GUI.skin.box); } return(true); }
protected void EndList(IPropertyContainer container, IListProperty property) { CurrentListProperty = null; if (ShouldHide(property)) { return; } PopEnabledState(); if (CanDrawAsList(property)) { // Commit any removed items if (RemoveAtIndex >= 0) { property.RemoveAt(container, RemoveAtIndex); RemoveAtIndex = -1; } if (Targets.Count > 1) { return; } EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if (GUILayout.Button("Add", GUILayout.Width(32.0f), GUILayout.Height(16.0f))) { property.AddNewItem(container); } GUILayout.Space(15.0f); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); GUILayout.Space(5.0f); EditorGUILayout.EndHorizontal(); } }
internal void InitListProperty(IListProperty value) { this._listProperty = value; }
/// <summary> /// 延迟加载子对象的集合。 /// </summary> /// <param name="listProperty">The list property.</param> /// <returns></returns> public EntityList GetLazyList(IListProperty listProperty) { return(this.LoadLazyList(listProperty)); }
public ClassListProperty(IListProperty property) : base(property) { }
/// <summary> /// 加载某个指定的组合子属性。 /// </summary> /// <param name="childrenProperty">组合子属性。</param> /// <param name="owner">该属性对应的具体类型。 /// 这个具体的类型必须是属性的拥有类型或者它的子类型。如果传入 null,则默认为属性的拥有类型。</param> /// <returns></returns> public EagerLoadOptions LoadWith(IListProperty childrenProperty, Type owner) { _eagerList.Add(new ConcreteProperty(childrenProperty, owner)); return(this); }
/// <summary> /// 加载某个指定的组合子属性。 /// </summary> /// <param name="childrenProperty">组合子属性。</param> /// <param name="owner">该属性对应的具体类型。 /// 这个具体的类型必须是属性的拥有类型或者它的子类型。如果传入 null,则默认为属性的拥有类型。</param> /// <returns></returns> public EagerLoadOptions LoadWith(IListProperty childrenProperty, Type owner) { _eagerList.Add(new ConcreteProperty(childrenProperty, owner)); return this; }
public ValueListProperty(IListProperty property) : base(property.Name) { m_Property = property; }
public static IEnumerable <IBusinessObjectBase> Get_PropertyTypes(IListProperty p, IObjectSpace os) { return(os.GetObjects <IBusinessObject>()); }
//(IProperty property, TypeBuilder type, Dictionary<IBusinessObjectBase, TypeBuilder> definedTypes) public void BuildProperty(IListProperty property, TypeBuilder type, Dictionary <IBusinessObjectBase, TypeBuilder> definedTypes) { BuildCollectionProperty(property, type, definedTypes); }
/// <summary> /// 通过一个聚合子实体属性构造一个界面块 /// 本构造函数直接使用该属性对应实体的默认视图中的名称作用本子块的 Label /// </summary> /// <param name="childrenProperty"></param> public ChildBlock(IListProperty childrenProperty) { if (childrenProperty == null) throw new ArgumentNullException("childrenProperty"); this.ChildrenProperty = childrenProperty; }
/// <summary> /// 对实体列表中每一个实体都贪婪加载出它的所有子实体。 /// </summary> /// <param name="list"></param> /// <param name="listProperty">贪婪加载的列表子属性。</param> /// <param name="eagerLoadProperties">所有还需要贪婪加载的属性。</param> private void EagerLoadChildren(EntityList list, IListProperty listProperty, List <ConcreteProperty> eagerLoadProperties) { //查询一个大的实体集合,包含列表中所有实体所需要的所有子实体。 var idList = new List <object>(10); list.EachNode(e => { idList.Add(e.Id); return(false); }); if (idList.Count > 0) { var targetRepo = RepositoryFactoryHost.Factory.FindByEntity(listProperty.ListEntityType); var allChildren = targetRepo.GetByParentIdList(idList.ToArray(), PagingInfo.Empty); //继续递归加载它的贪婪属性。 this.EagerLoad(allChildren, eagerLoadProperties); //把大的实体集合,根据父实体 Id,分拆到每一个父实体的子集合中。 var parentProperty = targetRepo.FindParentPropertyInfo(true).ManagedProperty as IRefProperty; var parentIdProperty = parentProperty.RefIdProperty; #region 把父实体全部放到排序列表中 //由于数据量可能较大,所以需要进行排序后再顺序加载。 IList <Entity> sortedList = null; if (_repository.SupportTree) { var sortedParents = new List <Entity>(list.Count); list.EachNode(p => { sortedParents.Add(p); return(false); }); sortedList = sortedParents.OrderBy(e => e.Id).ToList(); } else { sortedList = list.OrderBy(e => e.Id).ToList(); } #endregion #region 使用一次主循环就把所有的子实体都加载到父实体中。 //一次循环就能完全加载的前提是因为父集合按照 Id 排序,子集合按照父 Id 排序。 int pIndex = 0, pLength = sortedList.Count; var parent = sortedList[pIndex]; var children = targetRepo.NewList(); for (int i = 0, c = allChildren.Count; i < c; i++) { var child = allChildren[i]; var childPId = child.GetRefId(parentIdProperty); //必须把该子对象处理完成后,才能跳出下面的循环。 while (true) { if (object.Equals(childPId, parent.Id)) { children.Add(child); break; } else { //检测下一个父实体。 pIndex++; //所有父集合已经加载完毕,退出整个循环。 if (pIndex >= pLength) { i = c; break; } //把整理好的子集合,加载到父实体中。 children.SetParentEntity(parent); parent.LoadProperty(listProperty, children); //并同时更新变量。 parent = sortedList[pIndex]; children = targetRepo.NewList(); } } } if (children.Count > 0) { children.SetParentEntity(parent); } parent.LoadProperty(listProperty, children); //如果子集合处理完了,父集合还没有循环到最后,那么需要把余下的父实体的子集合都加载好。 pIndex++; while (pIndex < pLength) { parent.LoadProperty(listProperty, targetRepo.NewList()); pIndex++; } #endregion } }