ben*_*ree 9 c# dynamic ravendb
我正在使用RavenDB并需要存储动态数据,如:
public class User {
public string Name;
public dynamic Data;
}
Run Code Online (Sandbox Code Playgroud)
看来,我可以用很多不同的类型,比如dynamic,RavenJObject, DynamicJsonObject,ExpandoObject,Dictionary<string, object>,但我不知道它们的区别是什么.
有人可以解释动态数据的选项吗?我更关心查询以及更多关于轻松存储和检索的信息.
这是交易,如果你有一个dynamic属性,那么RavenDB将始终将其反序列化为RavenJObject.例如:
public class User {
public dynamic Data = new ExpandoObject();
}
...
var user = new User();
user.Data.SomethingNew1 = "foo";
Run Code Online (Sandbox Code Playgroud)
这看起来无害并且在您创建用户时工作正常.但是当你加载用户时,RavenDB不知道你想要什么类型,dynamic所以它使用RavenJObject.您无法动态创建属性(expando样式),RavenJObject因此失败:
var user = session.Find<User>(...);
user.Data.SomethingNew2 = "foo"; //compiles, but throws
Run Code Online (Sandbox Code Playgroud)
使用ExpandoObject并在序列化的属性中显式定义其类型.这让RavenDB(或我猜的JSON)知道你期望的类型,而且不必猜测RavenJObject.然后,为了保持你的语法魔力,用动态访问器包装属性.
public class User {
public ExpandoObject _Data = new ExpandoObject();
public dynamic Data {
get { return _Data; }
}
}
Run Code Online (Sandbox Code Playgroud)
有一些方法可以将expando对象设为私有并为其创建一个setter Data,但是你明白了.
更新:不幸的是,此解决方案暴露了更多问题 假设您在动态数据中存储字符串列表:
user.Data.Keys = new List<String>{"a","b","c"};
Run Code Online (Sandbox Code Playgroud)
序列化/反序列化后,JSON/Raven再次不知道您期望的类型.因此,如果你尝试这个(见下文)然后它编译但你得到一个运行时异常不能隐式地将类型'Raven.Abstractions.Linq.DynamicList'转换为'System.Collections.Generic.List':
List<string> keys = user.Data.Keys;
Run Code Online (Sandbox Code Playgroud)