英文:
cosmos GetItemLinqQueryable with ItemResponse without partitionKey
问题
我需要根据Id
参数查询容器,而不知道分区键,同时需要检索该项的ItemResponse以访问ETag属性。
通常情况下,如果有分区键,可以像这样轻松完成:
var orderEntity = await container.ReadItemAsync<OrderEntity>(orderId, new PartitionKey(partitionKeyValue));
但如果不知道分区键的值,该怎么办呢?
我尝试这样做:
var query = container.GetItemLinqQueryable<ItemResponse<OrderEntity>>(requestOptions: new QueryRequestOptions()).AsQueryable();
query = query.Where(t => t.Resource.Id == orderId);
但是如果我执行没有Where条件的查询,那么我会得到100个<ItemResponse <OrderEntity> >对象,但它们的Resource属性都为空。
英文:
I need to query container by Id
parameter without knowing partition key also I need to retrieve ItemResponse of that in order to reach ETag property
Normally with partion key this is easy to do with partition key, like this:
var orderEntity = await container.ReadItemAsync<OrderEntity>(orderId, new PartitionKey(partitionKeyValue));
but how to do if you don't know value for partition key ?
I tried to do it this way
var query = container.GetItemLinqQueryable<ItemResponse<OrderEntity>>(requestOptions: new QueryRequestOptions()).AsQueryable();
query = query.Where(t => t.Resource.Id == orderId);
But this returns me null, if I execute query without where condition then I got 100 objects of <ItemResponse <OrderEntity> > but Resource property is empty for all of them
答案1
得分: 1
一个ReadItem
操作通过其id
属性和分区键值来读取一个项。
当没有分区键时,你正在执行一个“跨分区查询”。
你要找的是像这样的东西:
var query = container.GetItemLinqQueryable<OrderEntity>(requestOptions: new QueryRequestOptions()).AsQueryable();
query = query.Where(t => t.Id == orderId);
假设在OrderEntity
中,你的Id
属性与一个id
序列化匹配(例如,你有[JsonProperty("id")]
)。如果有另一个属性与id
匹配,使用它。
与你在问题中的代码的主要区别在于,你不需要使用ItemResponse
,那只是ReadItem
返回的类型。在查询中,你正在查询你的项,因此使用表示你的项的POCO/类型。
请记住,跨分区查询可能会根据容器中的分区数量需要更长时间,确保排空所有页面,不要假设结果总是在第一页(如果你正在分页)。请参阅API文档中的示例:https://learn.microsoft.com/dotnet/api/microsoft.azure.cosmos.container.getitemlinqqueryable?view=azure-dotnet
英文:
A ReadItem
operation is reading an item by it's id
property and Partition Key Value.
When querying without the Partition Key, you are doing a "cross partition query".
What you are looking for is something like:
var query = container.GetItemLinqQueryable<OrderEntity>(requestOptions: new QueryRequestOptions()).AsQueryable();
query = query.Where(t => t.Id == orderId);
Assuming that in OrderEntity
, your Id
property matches with an id
serialization (you have for example [JsonProperty("id")]
). If there is another property that matches with id
, use that.
The main difference with your code in your question is that you don't need to use ItemResponse
, that is just the type that ReadItem
returns. In a query, you are querying over your items, so use the POCO/type that represents your items.
Remember that a cross partition query can take longer depending on the number of partitions in the container, and make sure you drain all pages, don't assume results will be always on the first page (if you are paging). See the examples on the API docs: https://learn.microsoft.com/dotnet/api/microsoft.azure.cosmos.container.getitemlinqqueryable?view=azure-dotnet
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论