Получение объектов из cosmos, относящихся к заданному типу класса (ISO: лучшая практика)

#c# #.net-core #azure-cosmosdb

#c# #.net-core #azure-cosmosdb

Вопрос:

библиотека nuget: Microsoft.Azure.Cosmos v3.14.0

Так что это была горячая минута с тех пор, как я работал с Azure Cosmos. Похоже, они обновили свой SDK. Итак, я пытаюсь выяснить, есть ли у меня какой-либо способ получить список записей, соответствующих типу класса.

Моя текущая идея состоит в том, чтобы просто взаимодействовать со всеми объектами класса, которые хранятся в cosmos, как с CosmosEntity, который имеет строку типа. Затем в этом методе GetAll я просто проверяю элемент, чтобы увидеть, соответствует ли он заданному типу.

На самом деле не следует, как я мог бы применить фильтр в этом, не используя параметр и не предоставляя ему тип. Даже рассматривал возможность использования отражения, но тогда, если я делаю это каждый раз, когда вызываю его, я беспокоюсь, как это повлияет на производительность.

Просто пытаюсь придерживаться наилучшей практики.

Итак! Вопрос в том!

Что было бы наилучшей практикой для получения объектов из cosmos, соответствующих типу T?

     public async Task<List<T>> GetAllEntities<T>() where T : CosmosEntity, new()
    {
        try
        {
            List<T> result = new List<T>();
            using (FeedIterator<T> feedIterator = _cosmosDatabase.GetItemQueryIterator<T>())
            {
                while (feedIterator.HasMoreResults)
                {
                    foreach (var item in await feedIterator.ReadNextAsync())
                    {                            
                        result.Add(item);
                    }
                }

                return resu<
            }
        }
        catch (Exception ex)
        {
            var x = 1;
            throw;
        }

    }
  

Комментарии:

1. Есть ли у вас также структура модели данных? Особенно важен ключ PartitionKey . Т.е. вы можете использовать PK в качестве имени T, чтобы ваш запрос просто считывал все элементы из раздела. Но это действительно зависит от ваших требований.

2. Поскольку Cosmos просто хранит текст, а тип является конструкцией .NET, вам потребуется какой-то механизм для определения типа записи. Я использую type свойство так, как вы описываете.

Ответ №1:

Вы можете следовать такому подходу:

 public async Task<DocDbQueryResult> QueryCollectionWithPagingInternalAsync<T>(FeedOptions feedOptions, string queryString, IDictionary<string, object> queryParams, string collectionName)
        {
            string continuationToken = feedOptions.RequestContinuation;
            List<JObject> documents = new List<JObject>();
            IDictionary<string, object> properties = new Dictionary<string, object>();
            int executionCount = 0;
            double requestCharge = default(double);
            double totalRequestCharge = default(double);

            do
            {
                feedOptions.RequestContinuation = continuationToken;
                var query = this.documentDbClient.CreateDocumentQuery<JObject>(
                    UriFactory.CreateDocumentCollectionUri(this.databaseName, collectionName),
                    new SqlQuerySpec
                    {
                        QueryText = queryString,
                        Parameters = ToSqlQueryParamtereCollection(queryParams),
                    },
                    feedOptions)
                .AsDocumentQuery();

                var response = await query.ExecuteNextAsync<JObject>().ConfigureAwait(false);
                documents.AddRange(response.AsEnumerable());
                executionCount  ;
                requestCharge = executionCount == 1 ? response.RequestCharge : requestCharge;
                totalRequestCharge  = response.RequestCharge;
                continuationToken = response.ResponseContinuation;
            }
            while (!string.IsNullOrWhiteSpace(continuationToken) amp;amp; documents.Count < feedOptions.MaxItemCount);

            var pagedDocuments = documents.Take(feedOptions.MaxItemCount.Value);
            var result = new DocDbQueryResult
            {
                ResultSet = JsonConvert.DeserializeObject<List<T>>(new JArray(pagedDocuments).ToString()),
                TotalResults = Convert.ToInt32(pagedDocuments.Count()),
                ContinuationToken = continuationToken
            };

            // if query params are not null, use existing query params also to be passed as properties.
            if (queryParams != null)
            {
                properties = queryParams;
            }

            properties.Add("TotalRequestCharge", totalRequestCharge);
            properties.Add("ExecutionCount", executionCount);

            return resu<
        }