private async ValueTask LoadFieldAsync(Entity owner, ReadonlyTransaction txn) { //TODO:*****暂简单实现,待存储引擎实现Select指定字段集后修改 var path1 = await LoadFieldPath(owner, MemberId1, txn); if (path1 == null) { owner.AddAttached(AliasName, null); return; } var mm2 = path1.Model.GetMember(MemberId2, true); if (mm2.Type != EntityMemberType.EntityRef) { owner.AddAttached(AliasName, path1.GetMember(MemberId2).BoxedValue); return; } var path2 = await LoadFieldPath(path1, MemberId2, txn); if (path2 == null) { owner.AddAttached(AliasName, null); return; } Debug.Assert(path2.Model.GetMember(MemberId3, true).Type != EntityMemberType.EntityRef); owner.AddAttached(AliasName, path2.GetMember(MemberId3).BoxedValue); }
internal async ValueTask LoadAsync(Entity owner, ReadonlyTransaction txn) { Debug.Assert(owner != null); if (MemberType == EntityMemberType.EntityRef) { if (Parent == null) //表示根级 { if (Childs != null && Childs.Count > 0) { for (int i = 0; i < Childs.Count; i++) //TODO:并发执行 { await Childs[i].LoadAsync(owner, txn); } } } else { await LoadEntityRefAsync(owner, txn); } } else if (MemberType == EntityMemberType.EntitySet) { throw new NotImplementedException(); } else { await LoadFieldAsync(owner, txn); } }
protected async ValueTask LoadIncludesAsync(IList <Entity> list, ReadonlyTransaction txn) { if (rootIncluder == null || list == null) { return; } for (int i = 0; i < list.Count; i++) //TODO:并行执行 { await rootIncluder.LoadAsync(list[i], txn); } }
private async ValueTask LoadEntityRefAsync(Entity owner, ReadonlyTransaction txn) { var target = await LoadFieldPath(owner, MemberId1, txn); owner.InitEntityRefForLoad(MemberId1, target); if (target != null && Childs != null && Childs.Count > 0) { for (int i = 0; i < Childs.Count; i++) //TODO:并发执行 { await Childs[i].LoadAsync(target, txn); } } }
private static async ValueTask <Entity> LoadFieldPath(Entity owner, ushort memberId, ReadonlyTransaction txn) { //TODO:从事务缓存内先查找是否存在 var refModel = (EntityRefModel)owner.Model.GetMember(memberId, true); var refId = owner.GetEntityId(refModel.FKMemberIds[0]); if (refId == null) { return(null); } ulong refModelId = refModel.RefModelIds[0]; if (refModel.IsAggregationRef) { refModelId = owner.GetUInt64(refModel.TypeMemberId); } return(await EntityStore.LoadAsync(refModelId, refId)); }
/// <summary> /// 执行查询并返回Entity[] /// </summary> /// <returns>返回值可能为null</returns> public async ValueTask <IList <Entity> > ToListAsync() { var app = await RuntimeContext.Current.GetApplicationModelAsync(IdUtil.GetAppIdFromModelId(modelId)); var model = await RuntimeContext.Current.GetModelAsync <EntityModel>(modelId); var indexModel = model.SysStoreOptions.Indexes.SingleOrDefault(t => t.IndexId == indexId); if (indexModel == null) { throw new Exception("Index not exists."); } if (indexModel.Global) { throw new NotImplementedException(); } //先判断是否需要快照读事务 //TODO:跨分区也需要 ReadonlyTransaction txn = rootIncluder == null ? null : new ReadonlyTransaction(); if (model.SysStoreOptions.HasPartitionKeys) { //分区表先根据PartionPredicate查询出相关分区,再依次扫描 ulong[] parts = await GetPartitions(app.StoreId, model); if (parts == null || parts.Length == 0) { return(null); } var list = new List <Entity>((int)(take <= 1000 ? take : 20)); uint skipped = 0; uint taken = 0; for (int i = 0; i < parts.Length; i++) { var partRes = await ExecLocalIndexScanAsync(indexModel, parts[i], skip - skipped, take - taken, true); if (partRes != null) { partRes.ForEachRow((kp, ks, vp, vs) => { list.Add(EntityStoreReader.ReadEntity(model, kp, ks, vp, vs)); }); skipped += partRes.Skipped; taken += (uint)partRes.Length; partRes.Dispose(); if (taken >= take) { break; } } } await LoadIncludesAsync(list, txn); return(list); } else { ulong groupId = await EntityStore.GetOrCreateGlobalTablePartition(app, indexModel.Owner, IntPtr.Zero); if (groupId == 0) { return(null); } var res = await ExecLocalIndexScanAsync(indexModel, groupId, skip, take, true); if (res == null || res.Length == 0) { return(null); } var list = new Entity[res.Length]; int rowIndex = 0; res.ForEachRow((kp, ks, vp, vs) => { list[rowIndex] = EntityStoreReader.ReadEntity(model, kp, ks, vp, vs); rowIndex++; }); res.Dispose(); await LoadIncludesAsync(list, txn); return(list); } }