Beispiel #1
0
        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);
        }
Beispiel #2
0
 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);
     }
 }
Beispiel #3
0
 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);
     }
 }
Beispiel #4
0
        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);
                }
            }
        }
Beispiel #5
0
        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));
        }
Beispiel #6
0
        /// <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);
            }
        }