在Raven中存储父母和子指针的树

时间:2013-03-19 15:37:23

标签: c# json.net ravendb

我有一个树结构,其中节点有子指针和父指针。我有一些问题让它很好地序列化(这将用于配置,因此它需要对操作/配置管理器有些可读),并且在尝试了序列化约定和属性的不同组合后,我仍然卡住了。

我的类型如下:

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字段,但这使得序列化程序忽略了所有字段。

1 个答案:

答案 0 :(得分:0)

并非所有内容都适合直接存储在数据库中。您已经展示了这种情景的一个很好的例子。如果您的最终用户会对此感到困惑,那么您想要针对它的任何疑问也会如此。

我的建议是拥有一个没有这些引用的树版本。序列化,看起来像这样:

{
  "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();

序列化过程中不会遵循方法,因此这是最容易做到的事情。