2017-06-21 42 views
1

對象,我有以下JSON:反序列化JSON與兒童通過ID

{ 
    "graph": { 
     "edges": [{ 
      "fromNode": "1", 
      "toNode": "2", 
      "distance": 200 
     }], 
     "nodes": [{ 
      "id": "1", 
      "lat": 10.402875, 
      "lng": 53.611151 
     }] 
    } 
} 

對於反序列化我有這個類:

public class Graph { 

    public Node [] nodes { get; set; } 
    public Edge [] edges { get; set; } 
} 

public class Node { 

    public string id { get; set; } 
    public double lat { get; set; } 
    public double lng { get; set; } 
} 

public class Edge { 

    public string fromNode { get; set; } 
    public string toNode { get; set; } 
    public int distance { get; set; } 
} 

當我想反序列化JSON我調用這個函數:

JsonConvert.DeserializeObject<Graph> (content); 

現在我想通過反序列化來獲得邊緣類中的引用節點對象,如下所示:

public class Edge { 

    public Node fromNode { get; set; } 
    public Node toNode { get; set; } 
    public int distance { get; set; } 
} 

在反序列化之後沒有foreach循環的例子嗎?

+0

您可以先修改JSon和解析節點嗎? – Mat

+1

這是不可能通過簡單的反序列化。一旦你使用反序列化獲得圖形對象,你需要編寫邏輯來獲取節點和節點對象,編號爲 –

+0

有沒有一個可選邏輯的例子來通過編號獲取對象? – Maxim

回答

0

我建議你寫extension methods的邊緣返回節點:

public static class ExtensionMethods 
    { 
     public static Node FromNode(this Edge edge, Graph graph){ 
      return graph.Nodes.FirstOrDefault(n => n.id.Equals(edge.fromNode); 
     } 

     public static Node ToNode(this Edge edge, Graph graph){ 
      return graph.Nodes.FirstOrDefault(n => n.id.Equals(edge.toNode); 
     } 
    } 

之後,你可以調用edge.FromNode(graph)和節點得到回來。好處是您不需要將方法放在Node類中檢索節點,也不需要在每條邊上保持父圖關係。

1

一種方法是編寫自己的JsonConverter(如圖所示Here),並在反序列化過程中跟蹤您的節點ID(例如,在Dictionnary中)。然後,您可以每次創建新的Node時簡單檢索相應的Edges

因此,在您自定義轉換你有這樣的事情:

public override object ReadJson(JsonReader reader, Type objectType 
     , object existingValue, JsonSerializer serializer) 
{ 

    Graph graph = new Graph(); 
    List<Edge> graphEdges = new List<Edge>(); 
    List<Node> graphNodes = new List<Node>(); 

    Dictionnary<int, List<Edge>> fromNodesMap = new Dictionnary<int, List<Edge>>(); 
    Dictionnary<int, List<Edge>> toNodesMap = new Dictionnary<int, List<Edge>>(); 

    /* Parse the 'edges' array, I'm omitting the reading stuff here */ 

    var edge = new Edge(); 

    int fromNode = Convert.ToInt32(((JValue)obj["fromNode"]).Value); 
    if (fromNodesMap.Contains(fromNode)) { 
     fromNodesMap[fromNode].Add(edge); 
    } else { 
     var edgeList = new List<Edge>(); 
     edgeList.Add(edge); 
     fromNodesMap.Add(fromNode, edgeList); 
    } 

    int toNode = Convert.ToInt32(((JValue)obj["toNode"]).Value); 
    if (toNodesMap.Contains(toNode)) { 
     toNodesMap[toNode].Add(edge); 
    } else { 
     var edgeList = new List<Edge>(); 
     edgeList.Add(edge); 
     toNodesMap.Add(toNode, edgeList); 
    } 

    edge.distance = Convert.ToInt32(((JValue)obj["distance"]).Value); 

    graphEdges.Add(edge); 

    /* Parse the 'nodes' array, I'm omitting the reading stuff here */ 

    var node = new Node(); 
    int nodeId = Convert.ToInt32(((JValue)obj["id"]).Value); 
    node.lat = Convert.ToDouble(((JValue)obj["lat"]).Value); 
    node.lng = Convert.ToDouble(((JValue)obj["lng"]).Value); 

    var listEdgesSameFrom = fromNodesMap[nodeId]; 
    foreach (var edge in listEdgesSameFrom) 
     edge.fromNode = node; 

    var listEdgesSameTo = toNodesMap[nodeId]; 
    foreach (var edge in listEdgesSameTo) 
     edge.toNode = node; 

    graphNodes.Add(node); 

    /* Read till end */ 

    graph.edges = graphEdges.ToArray(); 
    graph.nodes = graphNodes.ToArray(); 

    return graph; 
} 

免責聲明我沒有測試過,但邏輯是存在的。

現在我知道在那裏有foreach循環,但區別在於唯一的搜索就是從字典中獲取列表,而且我認爲這很簡單。我希望這有助於或至少給你另一種方式來看待它。