在Raven中存储带有父指针和子指针的树
本文关键字:指针 Raven 存储 | 更新日期: 2023-09-27 18:04:46
我有一个树结构,其中的节点既有子指针又有父指针。我在很好地序列化它时遇到了一些问题(这将用于配置,因此它需要对操作/配置管理器具有一定的可读性),并且在尝试了序列化约定和属性的不同组合之后,我仍然卡住了。
我的类型是这样的:
public class NestedConfigurationTree<T> where T : class
{
public InternalNode<T> _root { get; set; }
public class InternalNode<TValue> where TValue : class
{
public Dictionary<string, InternalNode<TValue>> _children { get; set; }
public InternalNode<TValue> _parent { get; set; }
public TValue _value { get; set; }
}
}
当我允许循环引用([JsonObject(IsReference = true)]
)时,每个节点得到的JSON看起来像这样:
"$id": "3",
"_children": {
"ConfigurationItem": {
"$id": "4",
"_children": {},
"_parent": {
"$ref": "3"
},
"_value": "Some value"
}
},
这显然会让最终用户感到困惑,他们不想要$id和_parent这些东西。由于父节点在文档结构中非常明显,我是否可以避免序列化它,并在加载时重新创建它?
还有,是否有可能避免拥有公共属性?我最初将其写为private readonly
字段,但这使得序列化器忽略了所有这些字段。
并非所有内容都适合直接存储在数据库中。您已经展示了这种场景的一个很好的例子。如果您的最终用户会对它感到困惑,那么您想要针对它编写的任何查询也会感到困惑。
我的建议是有一个没有这些引用的树版本。序列化,看起来像这样:
{
"Value" : "A",
"Children" : [
{
"Value" : "B",
"Children" : [
{
"Value" : "C",
"Children" : [
{
"Value" : "D",
}
]
},
{
"Value" : "E",
"Children" : [
{
"Value" : "F",
"Children" : []
},
{
"Value" : "G",
"Children" : []
}
]
}
]
}
]
}
在序列化时,您可以忽略父/子链接,而在反序列化时,您可以将它们重新连接起来。
您可以在自定义的JsonConverter
中完成所有这些,而不是使用第二组类,它为您提供了如何序列化或反序列化任何特定实体的细粒度控制。
另一个选项(也许是最简单的)是使用方法而不是属性来遍历链接。换句话说,不是:
Node Parent { get; }
IEnumerable<Node> Children { get; }
你可以使用:
Node GetParent();
IEnumerable<Node> GetChildren();
方法在序列化过程中不会被跟踪,所以这可能是最简单的事情。