async IAsyncEnumerable <EntityLoadingState> LoadEntitiesMetadataAsync()
        {
            await using var stream = await GetAllMetadataAsync().ConfigureAwait(false);

            foreach (var metadata in await DeserializeCollectionAsync <EntitySetMetadata>(stream))
            {
                yield return(EntityLoadingState.FromMetadata(metadata));
            }
        }
        static Type GetEntityArrayType(EntityLoadingState state)
        {
            Type entityType = EntityTypeLookup.GetValueOrDefault(state.Entity.Id.Entity);

            if (entityType == null)
            {
                entityType = typeof(string);
            }
            return(entityType.MakeArrayType());
        }
        async Task <object[]> GetBatchAsync(EntityLoadingState state, int offset)
        {
            var result = await _httpClient
                         .GetStreamAsync(
                $"api/dataprovider/batch?provider={state.Entity.Id.Provider}&entity={state.Entity.Id.Entity}&skip={offset}&take={FetchBatchSize}"
                )
                         .ConfigureAwait(false);

            var collection = await System.Text.Json.JsonSerializer.DeserializeAsync(result, GetEntityArrayType(state), JSONOptions);

            return(((Array)collection).Cast <object>().ToArray());
        }
        async Task FetchRequiredDataAsync(DataProviderProgression progression)
        {
            if (progression.HasMissingData())
            {
                EntityLoadingState entityState = progression.RemainingEntities.Span[0];
                int offset = entityState.Loaded;
                var entityDataContainer = GetEntityDataContainer(entityState.Entity.Id);

                var batchArray = await GetBatchAsync(entityState, offset);

                while (batchArray.Length > 0 && offset < entityState.Entity.Total)
                {
                    entityDataContainer.Append(batchArray);
                    offset     += batchArray.Length;
                    progression = progression.Update(batchArray.Length);

                    batchArray = await GetBatchAsync(entityState, offset);
                }
                entityDataContainer.CompleteLoading();

                await FetchRequiredDataAsync(progression.StartNextEntity());
            }
        }