如何在 RavenDB 中存储具有动态属性的 C# 对象?

How to store C# objects with dynamic properties in RavenDB?

我在尝试在 RavenDB

中保存具有动态 属性 的对象时遇到问题

我要保存的对象代表一个订单。该订单包含一个订单行列表,因此想象一下以下订单 class:

public class Order {
    public int Id { get; set; }
    public List<Orderline> Orderlines { get; set; }
}

而订单 class 是:

public class Orderline {
    public Product Product { get; set; }
    public int Quantity { get; set; }
    public dynamic Attributes { get; set; }
}

我要保存的对象(我将用 JSON 显示它);

{
    "Id": 0,
    "Orderlines": [
        {
            "Product": {
                "Id": 0,
                "Name": "Some product"
            },
            "Quantity": 1,
            "Attributes": {
                "color": "Red"
            }
        }
    ]
}

保存它不会引发任何错误
RavenDB 将 Order 对象存储为

{
    "Id": 0,
    "Orderlines": [
        {
            "Product": {
                "Id": 0,
                "Name": "Some product"
            },
            "Quantity": 1,
            "Attributes": {
                "$type": "Newtonsoft.Json.Linq.JObject, Newtonsoft.Json",
                "color": {
                    "$type": "Newtonsoft.Json.Linq.JValue, Newtonsoft.Json",
                    "$values": []
                }
            }
        }
    ]
}

请注意 Order.Orderlines[0].Attributes.color 的值 属性 未设置...

当我尝试将该对象序列化回我的 C# Order 对象时,出现以下异常;

Unable to cast object of type 'Raven.Imports.Newtonsoft.Json.Utilities.CollectionWrapper`1[Newtonsoft.Json.Linq.JToken]' to type 'Newtonsoft.Json.Linq.JValue'.

我哪里做错了,如何将这个对象存储在 RavenDB 数据库中并检索它?

您实际保存到属性中的类型是什么? 通常你会使用一些实际上是动态的东西,比如 ExpandoObject

存储类型为 'dynamic' 的动态 属性 显然是不够的。当我给属性 属性 ExpandoObject 类型时,RavenDB 像往常一样存储属性 属性 JSON(没有 $type 和 $values,所以很干净)

当从 RavenDB 数据库中取回它时,它反序列化回一个 ExpandoObject 对象。

尝试在 Razor 视图中显示 属性 时,确保将 ExpandoObject 属性 转换为动态对象(例如 'as dynamic')。