16
votes

I'm building a .Net Console application to read information in a DocumentDB. The console app has data coming from an EventHub and inserts/updates recent data as it comes into the cloud.

I am trying to read a singular document from DocumentDB and I can confirm that the Document Exists prior to requesting the Document.

 if (DocumentDBRepository<DocumentDBItem>.DoesItemExist(name))
 {
     device = await DocumentDBRepository<DocumentDBItem>.GetItemAsync(name);
 }

I used this tutorial from Microsoft about building a Repository for accessing the DocumentDB records, and was successful at using almost all of the methods. I can update/delete/query the DB but I cannot read a singular Item.

First it was throwing an exception requesting a PartitionKey. So I modified the method to add the PartitionKey being used by the DB to the request. As soon as I added the PartitionKey it throws another exception with a message, "Resource Not Found"

public static async Task<T> GetItemAsync(string id)
{
    try
    {
        RequestOptions options = new RequestOptions();
        options.PartitionKey = new PartitionKey("DeviceId");
        Document document = await client.ReadDocumentAsync(UriFactory.CreateDocumentUri(DatabaseId, CollectionId, id), options);
        return (T)(dynamic)document;
    }
    catch (DocumentClientException e)
    {
        if (e.StatusCode == HttpStatusCode.NotFound)
        {
            return null;
        }
        else
        {
            throw;
        }
    }
}

PartitionKeyFromAzure

I've already modified my calls to use "GetItemsAsyc" and get an IEnumerable of Documents and get the First item in the list, but it doesn't make sense why I can use all of the other methods from the tutorial but this one continues to throw exceptions saying, "Resource Not Found".

Exception I'm getting:

"Message: {\"Errors\":[\"Resource Not Found\"]}\r\nActivityId: e317ae66-6500-476c-b70e-c986c4cbf1d9, Request URI: /apps/e842e452-2347-4a8e-8588-2f5f8b4803ad/services/2c490552-a24d-4a9d-a786-992c07356545/partitions/0281cfdd-0c60-499f-be4a-289723a7dbf9/replicas/131336364114731886s"
1
Is that definitely the correct partition key for the document you're looking for, and I think you need to specify its value (which I can't see in your code)? I'm using code very similar to yours, except without the partition key (as I'm using a lower offer throughput that doesn't support it), and it works fine.Martin Costello
It's the only partition key I'm using for the DB, and the ID I'm passing to the method is the Key as the PartitionKey. In this case 'DeviceId'.Andrew Konken
In my case I was saving the partition key as an integer but I was searching it as a string so it was not working. Once I fixed that it worked properlyjoalcego
deviceid is partitionkey name, you need to use partition key value like device id number. Document id is the id of document which is associated with ID column. Hope this help.Rahul Jha

1 Answers

20
votes

As shown in the documentation, you need to provide the value of the partition key, not the name of the field which stores the partition key. Thus, you need to add the device Id as a parameter to your method and pass its value in to the PartitionKey constructor.

From the example:

// Read document. Needs the partition key and the ID to be specified
Document result = await client.ReadDocumentAsync(
    UriFactory.CreateDocumentUri("db", "coll", "XMS-001-FE24C"), 
    new RequestOptions { PartitionKey = new PartitionKey("XMS-0001") });

So for your code:

public static async Task<T> GetItemAsync(string id, string deviceId)
{
    try
    {
        RequestOptions options = new RequestOptions();
        options.PartitionKey = new PartitionKey(deviceId);
        Document document = await client.ReadDocumentAsync(UriFactory.CreateDocumentUri(DatabaseId, CollectionId, id), options);
        return (T)(dynamic)document;
    }
    catch (DocumentClientException e)
    {
        if (e.StatusCode == HttpStatusCode.NotFound)
        {
            return null;
        }
        else
        {
            throw;
        }
    }
}