#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<
}