2013-03-19 63 views
2

我有一個樹結構,其中節點同時具有子指針和父指針。我遇到了一些問題,以便很好地序列化(這將用於配置,因此它需要對操作/配置管理器稍微可讀),並且在嘗試使用序列化約定和屬性的不同組合後,我仍然陷入困境。在Raven中存儲具有父指針和子指針的樹

我的類型是這樣的:

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

+0

爲什麼最終用戶在尋找原始的JSON? – 2013-03-20 06:23:13

+0

@AyendeRahien:這是一個配置管理工具,它要求原始數據應該「在數據庫管理工具中易於編輯」。基本上,如果工具中斷,他們希望能夠進入數據庫並更改設置。 – carlpett 2013-03-20 06:44:17

回答

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

的方法沒有得到序列化過程中遵循,所以這可能是最容易做的事情。