Search code examples
c#azure-cosmosdbazure-cosmosdb-sqlapiazure-function-async

CosmosDB GetPropertyValue fails in foreachloop


I am trying to query my CosmosDB and then iterate over each document and get a value from a property in it to use but for some reason I am only getting null instead of the value

The query method looks as below

 private async Task<FeedResponse<Document>> FetchDocuments(string brand)
        {
            using (var client = new DocumentClient(new Uri(cosmosDBEndpointUrl), cosmosDBPrimaryKey))
            {
                FeedOptions queryOptions = new FeedOptions
                {
                    MaxItemCount = 0,
                    PartitionKey = new PartitionKey(brand)
                };

                var query = client.CreateDocumentQuery<Document>(UriFactory.CreateDocumentCollectionUri(cosmosDBName, cosmosDBCollectionNameRawData), $"SELECT * from c where c.brand = \"{brand}\"", queryOptions).AsDocumentQuery();
                var result = await query.ExecuteNextAsync<Document>();

                return result;
            }
        }

I then loop through the result like this

 var rawDataDocumentList = await FetchDocuments(brand);

 foreach (var singleDoc in rawDataDocumentList)
{
                string jongel = singleDoc.GetPropertyValue<string>("OriginalData.artno");
}

if I break in the loop I can see that I have actual data in there but for some reason it starts and ends with {{ }} where I expected a single { } pr maybe I am missing something here? well I know I AM missing something the question is what since jongel is always null

I rewrote my method as follows but the same problem persists

 private async Task<List<String>> FetchDocuments(string brand)
        {
            using (var client = new DocumentClient(new Uri(cosmosDBEndpointUrl), cosmosDBPrimaryKey))
            {
                List<string> documentListInLoop = new List<string>();
                FeedOptions queryOptions = new FeedOptions
                {
                    MaxItemCount = -1,
                    PartitionKey = new PartitionKey(brand)
                };

                var query = client.CreateDocumentQuery<Document>(UriFactory.CreateDocumentCollectionUri(cosmosDBName, cosmosDBCollectionNameRawData), $"SELECT * from c where c.brand = \"{brand}\"", queryOptions).AsDocumentQuery();

                while(query.HasMoreResults)
                {
                    foreach (Document singleDocument in await query.ExecuteNextAsync<Document>())
                    {
                        string artNo = singleDocument.GetPropertyValue<string>("OriginalData.artno");
                        documentListInLoop.Add(Newtonsoft.Json.JsonConvert.SerializeObject(singleDocument.ToString()));
                    }
                }
                //var result = await query.ExecuteNextAsync<Document>();

                return documentListInLoop;
            }
        }

I can see the artno property if I put a breakpoint and it looks as follows

 {{
  "brand": "XX",
  "UpdatedAt": "2019-10-24T00:31:18",
  "OriginalData": {
    "id": "a2303ce5-bb28-4d90-90ad-f741327b416a",
    "_id": "5da4eec9ee3b9100013f7e49",
    "artno": "0697054056",
    "vendor": "hm",
    "updatedAt": "2019-10-22T22:02:01.365Z",
    "locales": [

I cut this off to save space, as you can see it starts with double angle brackets not sure why?

And I cannot get any value for the artno even though its clearly there so I must be accessing the wrong way but I cannot figure out what I am doing wrong.


Solution

  • It's totally normal that you see two brackets in your object, Visual Studio adds them in the preview of a property. The next thing is, that you want to access a nested property of the document. Therefore you could get the json property as follows:

    using Newtonsoft.Json.Linq;
    
    foreach (Document singleDocument in await query.ExecuteNextAsync<Document>())
    {
        string artNo = singleDocument.GetPropertyValue<JObject>("OriginalData")["artno"]?.ToString();
        // some other code...
    }