处理多种类型的 Cosmos DB 容器的读取?

Mic*_*hev 6 azure-cosmosdb azure-cosmosdb-sqlapi

我想在单个 Cosmos DB 容器中存储几种不同的对象类型,因为它们都按逻辑分组,并且可以按时间戳一起读取,以避免额外的 HTTP 调用。

但是,Cosmos DB 客户端 API 似乎没有提供一种简单的方法来执行多种类型的读取。到目前为止,我找到的最好的解决方案是编写自己的 CosmosSerializer 和 JsonConverter,但这感觉很笨拙:https ://thomaslevesque.com/2019/10/15/handling-type-hierarchies-in-cosmos-db-part -2/

是否有一种更优雅的方法来将不同类型的项目读取到共享基类,以便我可以稍后转换它们,或者我是否必须接受打击?

谢谢!

Mar*_*own 8

我这样做的方法是将 ItemQueryIterator 和 FeedResponse 对象创建为动态对象,并最初以非类型化方式读取它们,这样我就可以检查“type”属性,该属性告诉我要反序列化到什么类型的对象。

在此示例中,我有一个容器,其中包含我的客户数据及其所有销售订单。代码如下所示。

        string sql = "SELECT * from c WHERE c.customerId = @customerId";

        FeedIterator<dynamic> resultSet = container.GetItemQueryIterator<dynamic>(
            new QueryDefinition(sql)
            .WithParameter("@customerId", customerId),
            requestOptions: new QueryRequestOptions 
            { 
                PartitionKey = new PartitionKey(customerId) 
            });

        CustomerV4 customer = new CustomerV4();
        List<SalesOrder> orders = new List<SalesOrder>();

        while (resultSet.HasMoreResults)
        {
            //dynamic response. Deserialize into POCO's based upon "type" property
            FeedResponse<dynamic> response = await resultSet.ReadNextAsync();
            foreach (var item in response)
            {
                if (item.type == "customer")
                {
                    customer = JsonConvert.DeserializeObject<CustomerV4>(item.ToString());
                    
                }
                else if (item.type == "salesOrder")
                {
                    orders.Add(JsonConvert.DeserializeObject<SalesOrder>(item.ToString()));
                }
            }
        }
Run Code Online (Sandbox Code Playgroud)

更新:

如果想要创建“基本文档”类然后从中派生,则不必使用动态类型。反序列化到documentBase类中,然后检查type属性以检查将有效负载反序列化到哪个类中。

当您使用 docVersion 属性随着时间的推移发展数据模型时,您还可以扩展此模式。

在此输入图像描述