2

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

我的类型如下所示:

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

4

1 回答 1

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

在序列化过程中不会遵循方法,因此这可能是最简单的事情。

于 2013-03-19T21:44:28.637 回答