Сущность CosmosDB с указанным идентификатором не существует - PullRequest
0 голосов
/ 18 мая 2019

Я занимаюсь разработкой ASP.NET Core MVC API для вызова ресурсов в базе данных Azure Cosmos. Когда я пытаюсь выполнить GET для любого конкретного идентификатора, я получаю DocumentClientException: объект с указанным идентификатором не существует в системе. Я могу подтвердить, что сущность существует в системе, и соединение успешно, потому что я могу успешно выполнять другие методы и запросы. Ключ раздела - _id.

Отладка с помощью точек останова в Visual Studio, я могу видеть, где в API получен правильный идентификатор, но не могу подтвердить, что именно он отправляет в Azure

Методы контроллера: (поле идентификатора представляет собой случайную строку цифр и текста)

        //controller is MoviesController decorated with [Route(api/[controller])]
    //sample GET is to localhost:port/api/Movies/5ca6gdwndkna99
        [HttpGet("{id}")]
        public async Task<MoviesModel> Get(string id)
        {
            MoviesModel movie = await _persistence.GetMovieAsync(id);
            return movie;
        }

Метод обработки данных:

public async Task<MoviesModel> GetMovieAsync(string Id)
        {

            string _id = Id;
            RequestOptions options = new RequestOptions();
            options.PartitionKey = new PartitionKey(_id);
            var documentUri = UriFactory.CreateDocumentUri(_databaseId, "movies", Id);
            Document result = await _client.ReadDocumentAsync(documentUri,options);

            return (MoviesModel)(dynamic)result;
        }

Другие методы, такие как получение списка всех фильмов и возврат к таблице, работают нормально, поэтому мы можем исключить проблемы с сетью

public async Task<List<MoviesModel>> GetMoviesAsync() 
{
var documentCollectionUri = UriFactory.CreateDocumentCollectionUri(_databaseId, "movies");

            // build the query
            var feedOptions = new FeedOptions() { EnableCrossPartitionQuery = true };
            var query = _client.CreateDocumentQuery<MoviesModel>(documentCollectionUri, "SELECT * FROM movies", feedOptions);
            var queryAll = query.AsDocumentQuery();

            // combine the results
            var results = new List<MoviesModel>();
            while (queryAll.HasMoreResults)
            {
                results.AddRange(await queryAll.ExecuteNextAsync<MoviesModel>());
            }

            return results;
        }


        public async Task<List<GenresModel>> GetGenresAsync()
        {
            await EnsureSetupAsync();

            var documentCollectionUri = UriFactory.CreateDocumentCollectionUri(_databaseId, "genres");

            // build the query
            var feedOptions = new FeedOptions() { EnableCrossPartitionQuery = true };
            var query = _client.CreateDocumentQuery<GenresModel>(documentCollectionUri, "SELECT * FROM genres", feedOptions);
            var queryAll = query.AsDocumentQuery();

            // combine the results
            var results = new List<GenresModel>();
            while (queryAll.HasMoreResults)
            {
                results.AddRange(await queryAll.ExecuteNextAsync<GenresModel>());
            }

            return results;
        }

Ответы [ 2 ]

0 голосов
/ 18 мая 2019

Мне удалось заставить это работать, полностью изменив рефакторинг на dotnet v3 SDK. Мой код для решения в комментариях ссылки на gitHub.

0 голосов
/ 18 мая 2019

Во-первых, я бы предложил один раз пересмотреть ваш дизайн cosmosDb, bcz по следующим причинам ...

Проблемы:

  1. Если ваш _id - это случайная строка чисел и текста, то не лучше иметь весь _id в качестве ключа раздела, bcz это создаст новый раздел для каждой записи (хотя azure будет разбивать его на разделы позже)

  2. Запросы только по ключу раздела не эффективны, для точечных запросов у нас должен быть и ключ раздела, и ключ строки.

Решение :

  1. Введите первые одну или две буквы своего _id в качестве ключа раздела.(поэтому ваши разделы будут конечными).

  2. Сделайте _id своим ключом строки.

  3. Если ваш _id = "abwed123asdf", тогдаВаш запрос должен быть ..

    RequestOptions options = new RequestOptions ();

    options.PartitionKey = new PartitionKey (_id.Substring (0,1));

    options.RowKey = _id;

Таким образом, ваш поиск будет точно указывать на нужную запись с помощью ключа раздела и строки.(экономит много RU)

Пожалуйста, обратитесь к документации для выбора более подходящих ключей разделов для ваших нужд https://docs.microsoft.com/en-us/azure/cosmos-db/partitioning-overview

...