protected override void Insert(Entity entity) { EnsureStore(); string key = this.GetRealKey(entity); //在生成 Id 时,为某个模型生成临时使用的本地 Id。 if (!entity.HasId) { var found = this.FindByRealKey(key); if (found != null) { //如果这个实体已经存在于内存中,则更新新对象的 Id,并在最后把新对象的数据存储起来即可。 entity.LoadProperty(Entity.IdProperty, found.Id); } else { var newId = entity.KeyProvider.NewLocalId(); entity.LoadProperty(Entity.IdProperty, newId); } } //有些实体并不一定通过 CDU 接口保存到 _memoryRows 中,而是在查询时临时生成。 //这时,也需要把这些实体都加入到 _memoryRows 中。 _memoryRows[key] = ToRow(entity); }
/// <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; } } } } }
private void TrySetProperty(Entity e, string pName, JToken value) { //有些小写的客户端数据被传输到了服务端,需要被过滤掉。 if (char.IsLower(pName[0])) { return; } var pm = _entityMeta.Property(pName) as PropertyMeta ?? _entityMeta.ChildrenProperty(pName); if (pm != null) { var mp = pm.ManagedProperty; if (mp is IListProperty) { //todo: 此处的性能可能需要优化,聚合保存子列表时,重复的查询 Repository var entityType = EntityMatrix.FindByList(pm.PropertyType).EntityType; var repo = RF.Find(entityType); //列表属性的设置不能使用 SetProperty,否则,list.Parent 将会无值。 //但是也不能直接使用 LoadProperty,否则会导致调用 list.MarkOld,从而不会保存这个列表。 //所以只能先装载一个空列表,然后再把 json 中的数据转换为实体加入到这个列表中。 var list = repo.NewList(); e.LoadProperty(mp, list); ListReader.JsonToEntity(value as JObject, repo, list); } else { var rawValue = (value as JValue).Value; rawValue = EntityJsonConverter.ToServerValue(pm.PropertyType, rawValue); e.SetProperty(mp, rawValue, ManagedPropertyChangedSource.FromUIOperating); } } else { var rawValue = (value as JValue).Value; //如果没有找到一般的属性,则尝试查找外键属性 for (int i = 0, c = _refIdProperties.Count; i < c; i++) { var rip = _refIdProperties[i]; if (rip.Name == pName) { e.SetRefId(rip, rawValue); break; } } //只读属性。 //if(notFound) //{ // throw new InvalidOperationException("没有在实体中找到这个属性:" + pName); //} } }