简体   繁体   中英

Confusion about CreateItemAsync and new PartitionKey in Azure Cosmos DB - .NET Core

I am trying to setup a simple console project with Azure Cosmos DB. I am confused about the Partition Key Usage.

Note, I have already looked at this solution, but I believe I have a slightly different situation.

I am setting up the container like this.

private string PartitionKeyPath = "/ProductPartitionKey";
this.container = await this.database.CreateContainerIfNotExistsAsync(containerId, PartitionKeyPath);

Here is an example JSON, as it gets stored in the container. So, I am successful in getting items added.

{
    "Name": "Super Curtain",
    "UnitPrice": 500,
    "id": "124BBC08-F51C-4ED4-B961-8DD0C966F66F",
    "ProductPartitionKey": "Hello",
    "_rid": "m2VTANekt8ACAAAAAAAAAA==",
    "_self": "dbs/m2VTAA==/colls/m2VTANekt8A=/docs/m2VTANekt8ACAAAAAAAAAA==/",
    "_etag": "\"0500753f-0000-1800-0000-5f735ac70000\"",
    "_attachments": "attachments/",
    "_ts": 1601395399
}

I am able to do an insert with both the following lines of usage.

var tempPartitionKey = new PartitionKey(tempProduct.ProductPartitionKey);

ItemResponse < Product > tempProductResponse = await this.container.CreateItemAsync < Product > (tempProduct, tempPartitionKey);
ItemResponse < Product > tempProductResponse = await this.container.CreateItemAsync < Product > (tempProduct);

The issue is, why wont the following work?

var tempPartitionKey2 = new PartitionKey("/ProductPartitionKey");
ItemResponse < Product > tempProductResponse = await this.container.CreateItemAsync < Product > (tempProduct, tempPartitionKey2);

or this.

var tempPartitionKey3 = new PartitionKey("ProductPartitionKey");
ItemResponse<Product> tempProductResponse = await this.container.CreateItemAsync<Product>(tempProduct, tempPartitionKey3);

I get the same error in the linked stack question.

PartitionKey extracted from document doesn't match the one specified in the header

so, ultimately, I am trying to understand, what string literal can I use, with new PartitionKey()?

Or,

is it so that, at current point of time, this is the only way to set and use Partition Key and I should not be trying to set the Partition Key with direct, string literal values? Perhaps, it is not a good way to do this, and azure cosmos library has stopped or removed that ability.

var tempPartitionKey2 = new PartitionKey("/ProductPartitionKey");
ItemResponse < Product > tempProductResponse = await this.container.CreateItemAsync < Product > (tempProduct, tempPartitionKey2);

This does not work because you are not passing the Partition Key Value, you are passing the name of the property configured as Partition Key Path in the Container.

The error comes when the backend receives your item Json, and sees that the value does not correspond with that the item Json has.

When creating an item, the operation requires the item content, plus the value of the Partition Key Path for that document, the Partition Key Value. That is why this works:

var tempPartitionKey = new PartitionKey(tempProduct.ProductPartitionKey);

ItemResponse < Product > tempProductResponse = await this.container.CreateItemAsync < Product > (tempProduct, tempPartitionKey);

because you are passing the value of the property.

If you don't specify the PartitionKey parameter, the SDK needs to extract it from the item payload, which takes a performance/CPU hit. So it is recommended that, if you can, specify the value as the PartitionKey parameter.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM