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" : []
            }
          ]
        }
      ]
    }
  ]
}

シリアル化するときは親/子リンクを無視し、逆シリアル化するときはそれらをバックアップします。

クラスの2番目のセットの代わりに、これをすべてカスタムで行うことができます。これJsonConverterにより、特定のエンティティをシリアル化または逆シリアル化する方法をきめ細かく制御できます。

別のオプション(そしておそらく最も簡単なオプション)は、トラバーサルリンクのプロパティの代わりにメソッドを使用することです。言い換えれば、代わりに:

Node Parent { get; }
IEnumerable<Node> Children { get; }

次を使用します:

Node GetParent();
IEnumerable<Node> GetChildren();

シリアル化中はメソッドが実行されないため、これが最も簡単な方法です。

于 2013-03-19T21:44:28.637 に答える