#c# #azure-cosmosdb
#c# #azure-cosmosdb
Вопрос:
Я сталкиваюсь с проблемой при попытке удалить документ из CosmosDb
, насколько я понимаю, сначала мне нужно загрузить документ, который я хочу удалить, а затем передать document.SelfLink
в следующий метод:
DeleteDocumentAsync
Однако, когда я пытаюсь удалить его, он выдает следующую ошибку:
объект с указанным идентификатором не существует в системе
Я знаю, что документ существует, поскольку я могу видеть документ в document
переменной.
Ниже приведена моя текущая настройка кода:
private static void DeleteDocument()
{
var feedOptions = new FeedOptions
{
MaxItemCount = -1,
EnableCrossPartitionQuery = true
};
var document = _documentClient
.CreateDocumentQuery(UriFactory.CreateDocumentCollectionUri(_databaseName, _collection), feedOptions)
.Where(x => x.Id == "ba00d500-de61-411e-b8ef-f749b23cc326")
.AsEnumerable()
.SingleOrDefault();
if (document == null) return; // Document is not null when I check here
_documentClient.DeleteDocumentAsync(UriFactory.CreateDocumentUri(_databaseName, _collection, document.Id), new RequestOptions { PartitionKey = new Microsoft.Azure.Documents.PartitionKey(document.Id) })
.GetAwaiter()
.GetResult();
}
Вот документ в CosmosDB:
Я также пытался ссылаться на document.SelfLink
вместо использования UriFactory.CreateDocumentUrl
, но результат все тот же.
Обновить.
Кажется, что передача Undefined.Value
выполняется, поскольку PartitionKey
, похоже, работает:
_documentClient.DeleteDocumentAsync(document.SelfLink, new RequestOptions { PartitionKey = new Microsoft.Azure.Documents.PartitionKey(Undefined.Value) })
.GetAwaiter()
.GetResult();
Что лично я нахожу действительно странным.
Комментарии:
1. Документ имеет
id
(нижний регистр), но ваш предикат Linq имеетId
(и вы ссылаетесьdocument.Id
)
Ответ №1:
Я не вижу ничего странного, просто нужно знать ключ раздела и указывать его при отправке запроса на сервер. Ключ раздела является частью идентификатора документа так же, как id
и -field . Даже если ключ раздела undefined
.
Когда вы запрашивали документы, вы явно запрашивали сканирование всех разделов, EnableCrossPartitionQuery = true
что позволяло вам исключить ключ раздела из запроса и все равно получать результаты. Вы также должны были передать ключ раздела там, чтобы сэкономить затраты, но это работает.
Для удаления нет межсекционных удалений, и вы должны передать ключ раздела. Как только вы это сделали, документ был найден и его можно было удалить. Вполне ожидаемо.
Кроме того, НЕТ, вам не нужно загружать документ, чтобы удалить его, это просто дополнительная сложность, стоимость и сервер roundtripto. Все, что вам нужно знать, это идентификатор удаляемого документа (база данных коллекция раздел идентификатор). Для клиента CosmosDB V2, аналогичного этому примеру:
var documentUri = UriFactory.CreateDocumentUri(databaseName, containerName, documentId);
var options = new RequestOptions() { PartitionKey = new PartitionKey(partition) };
await cosmosClient.DeleteDocumentAsync(documentUri, options).ConfigureAwait(false);