如何将Azure DocumentDB Document类转换为POCO类?

时间:2018-07-18 21:14:11

标签: c# azure azure-cosmosdb

是否可以将Microsoft.Azure.Documents.Document对象转换为我的类类型?

我已经编写了一个带有CosmosDBTrigger的Azure Function类。触发器接收一个Microsoft.Azure.Documents.Document数组。我喜欢使用Document类,以便可以访问有关记录本身的元数据,但是我也想以静态方式与我的类类型中的数据进行交互。

当我调用ToString时,可以看到数据的JSON表示形式。我应该使用Newtonsoft将该JSON手动转换为我的类类型吗?

3 个答案:

答案 0 :(得分:3)

虽然尼克·查普萨斯(Nick Chapsas)提供的解决方案有效,但我想提供一些更好的选择。

首选解决方案-改进您的模型

首先,如果您对额外的元字段感兴趣,那么您始终可以将所选属性包括在数据访问模型中,并且这些属性将被填写。例如:

public class Model
{
    public String id { get; set; }
    public String _etag { get; set; }
    //etc.
}

然后,您可以使用现有的API对所有人显式且熟悉的序列进行反序列化。例如:

var explicitResult = await client.ReadDocumentAsync<Model>(documentUri);
Model explicitModel = explicitResult.Document;

如果您希望下一层模型(例如:域模型)不具有那些特定于存储的元字段,那么您需要转换为另一种模型,但这不再是cosmosDB级别的问题,并且有很多通用的映射器在POCO之间进行转换。

如果您使用强类型文档模型,这是在cosmosDB中处理数据访问的IMHO最干净和推荐的方法。

替代:动态

另一个技巧是使用动态作为中间铸造步骤。这在某种程度上是短暂而优雅的,但是个人使用动态总是感觉有点脏:

var documentResult = await client.ReadDocumentAsync(documentUri);
Model dynamicModel = (dynamic)documentResult.Resource;

替代:阅读JObject

另一种替代方法是将文档读取为NewtonSoft的JObject。这还将包括所有meta字段,您可以自己进行进一步转换,而无需在字符串表示之间进行所有额外的跳跃。示例:

var jObjectResult = await client.ReadDocumentAsync<JObject>(documentUri);
Model JObjectResult = jObjectResult.Document.ToObject<Model>();

替代:Document + JObject同时

如果您确实希望避免模型中的文档级元字段并仍然访问它们,则可以使用一些反射技巧来从JObject实例中获取Document

var documentResult = await client.ReadDocumentAsync(documentUri);
Document documentModel = documentResult.Resource;

var propertyBagMember = documentResult.Resource.GetType()
    .GetField("propertyBag", BindingFlags.NonPublic| BindingFlags.Instance);
Model reflectionModel = ((JObject)propertyBagMember.GetValue(documentResult.Resource))
    .ToObject<Model>();

请注意,反射技巧依赖于内部实现细节,并且不受库作者的向后兼容性保证。

答案 1 :(得分:2)

如果您需要在函数中将Document映射到POCO,那么最简单的方法就是您的建议。

调用document.Resource.ToString()方法并使用JSON.NET或您喜欢的json库中的DeserializeObject。推荐使用JSON.NET,因为Microsoft的CosmosDB库也要使用它。

您的映射调用将如下所示:

var yourPoco = JsonConvert.DeserializeObject<YourPocoType>(document.Resource.ToString())

答案 2 :(得分:0)

您只需在 type increase diff date 0 a 1600.000000 48 2/1/2020 1 b -23.076923 -3 2/1/2020 类中进行一个.ToString()

该类继承自Microsoft.Azure.Documents.Document方法的Microsoft.Azure.Documents.JsonSerializable类。

以下是使用新的高性能.ToString()命名空间将Document类反序列化为我的Car.cs POCO的示例:

System.Text.Json