在RavenDB中存储/检索动态数据

时间:2012-04-09 03:16:40

标签: c# dynamic ravendb

我正在使用RavenDB&需要存储动态数据,如:

public class User {
    public string Name;
    public dynamic Data;
}

我似乎可以使用许多不同类型,例如dynamicRavenJObjectDynamicJsonObjectExpandoObjectDictionary<string, object>,但我不知道差异是什么。

有人可以解释动态数据的选项吗?我更少关心查询&amp;更多关于轻松存储的信息检索。

2 个答案:

答案 0 :(得分:6)

问题

这是交易,如果您有dynamic属性,那么RavenDB 总是将其反序列化为RavenJObject。例如:

public class User {
    public dynamic Data = new ExpandoObject();
}

...

var user = new User();
user.Data.SomethingNew1 = "foo";

这看起来无害&amp;在创建用户时工作正常。但是当您加载用户时,RavenDB不知道dynamic所需的类型,因此它使用RavenJObject。您无法使用RavenJObject动态创建属性(expando样式),因此失败:

var user = session.Find<User>(...);
user.Data.SomethingNew2 = "foo"; //compiles, but throws

我的解决方案

使用ExpandoObject并在序列化的属性中明确定义其类型。这让RavenDB(或我猜的JSON)知道你期待什么类型&amp;它不必猜测RavenJObject。然后,为了保持你的语法魔力,用动态访问器包装属性。

public class User {
    public ExpandoObject _Data = new ExpandoObject();

    public dynamic Data {
        get { return _Data; }
    }
}

有一些方法可以使expando对象成为私有对象。为Data创建一个setter,但你明白了。

更多问题

更新:不幸的是,此解决方案暴露出更多问题。假设您在动态数据中存储字符串列表:

user.Data.Keys = new List<String>{"a","b","c"};

序列化/反序列化后,JSON / Raven再次不知道您期望的类型。因此,如果你尝试这个(见下文)然后它编译但你得到一个运行时异常不能隐式地将类型'Raven.Abstractions.Linq.DynamicList'转换为'System.Collections.Generic.List':< / p>

List<string> keys = user.Data.Keys;

答案 1 :(得分:4)

对于所有这些,你的内存类型是什么并不重要。

对象,动态和DynamicJsonObject是相同的 - 就RavenDB而言。它给你一个 使用RavenJObject作为后端的动态实现。

RavenJObject实际上只是从服务器获得的值。

ExpandoObject和Dictionary序列化为/来自词典,是全部。