最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c# - Azure Cosmos Client how to query for one item correctly without using its id - Stack Overflow

programmeradmin1浏览0评论

Today i stumbled over an Azure Cosmos DB Issue and still do not fully understand how my usecase should be handled correctly. Here's my original code:

using var setIterator = container.GetItemLinqQueryable<Baureihe>(requestOptions: RequestOptions)
    .Where(b => b.MarkeSlug == markeSlug.ToLower() && b.Slug == baureiheSlug.ToLower())  
    .ToFeedIterator();  
  
if (setIterator.HasMoreResults is false)  
{  
    return new NotFoundResult();  
}  
  
var response = await setIterator.ReadNextAsync();  
var baureihe = response.First();

This last line created null-reference exceptions if no items was found. I thought that this would have been covered by the setIterator.HasMoreResults is false but it is obviously not.

So I changed my last line to

var baureihe = response.First();
if (baureihe == null)  
{  
    return new NotFoundResult();  
}

So my questions are:

  1. Can I skip the setIterator.HasMoreResults is false check entirely, if I know that i would only get maximum one result?
  2. is there a generally better way to solve this issue? (access by Id is not possible unfortunately)

Today i stumbled over an Azure Cosmos DB Issue and still do not fully understand how my usecase should be handled correctly. Here's my original code:

using var setIterator = container.GetItemLinqQueryable<Baureihe>(requestOptions: RequestOptions)
    .Where(b => b.MarkeSlug == markeSlug.ToLower() && b.Slug == baureiheSlug.ToLower())  
    .ToFeedIterator();  
  
if (setIterator.HasMoreResults is false)  
{  
    return new NotFoundResult();  
}  
  
var response = await setIterator.ReadNextAsync();  
var baureihe = response.First();

This last line created null-reference exceptions if no items was found. I thought that this would have been covered by the setIterator.HasMoreResults is false but it is obviously not.

So I changed my last line to

var baureihe = response.First();
if (baureihe == null)  
{  
    return new NotFoundResult();  
}

So my questions are:

  1. Can I skip the setIterator.HasMoreResults is false check entirely, if I know that i would only get maximum one result?
  2. is there a generally better way to solve this issue? (access by Id is not possible unfortunately)
Share Improve this question asked Mar 13 at 14:38 JanJan 4,2453 gold badges34 silver badges53 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 3

If HasMoreResults is false you can safely say there's no results to the query so that check is fine. However your query might not be able to get the results back in its first request. So until you receive your result you'll have to loop over every page till there's no more results.

while (iterator.HasMoreResults)
{
    var feed = await iterator.ReadNextAsync();
    if (feed.FirstOrDefault() is Baureihe baureihe)
    {
        // do something with baureihe
        return OkObjectResult(baureihe);
    }
}

// at this point no results have come up and `HasMoreResults` is false
return new NotFoundResult();

I would not skip the .HasMoreResults check, as the MS documentation that states "In Azure Cosmos DB for NoSQL, queries may have multiple pages of results";' although, as per your question, the MS docs make no mention of results with a single result (such as a total, etc.).

Regarding a better way to solve the issue -- Some query examples are also given in the docs, see:

https://github/Azure/azure-cosmos-dotnet-v3/blob/master/Microsoft.Azure.Cosmos.Samples/Usage/Queries/Program.cs#L294

Hope that helps!

发布评论

评论列表(0)

  1. 暂无评论