2013-10-08 11 views
7

C# | .NET 4.5 | Entity Framework 5JSON-Hierarchie aus strukturierten Daten erstellen

Ich habe Daten aus einer SQL-Abfrage in Form von ID, ParentID, Name zurück. Ich möchte diese Daten nehmen und in eine hierarchische JSON-Zeichenfolge parsen. Bis jetzt scheint es viel mehr eine entmutigende Aufgabe zu sein, als es sein sollte. Da ich Entity verwende, kommen die Daten für mich als IEnumerable zurück. Jetzt glaube ich, ich brauche nur eine Form der Rekursion, aber ich bin mir nicht sicher, wo ich anfangen soll. Jede Hilfe wird geschätzt.

Daten Kosten als

 
id parentId name 
1 1   TopLoc 
2 1   Loc1 
3 1   Loc2 
4 2   Loc1A 

-Code

public static string GetJsonLocationHierarchy(long locationID) 
{ 
    using (EntitiesSettings context = new EntitiesSettings()) 
    { 
     // IEnumerable of ID,ParentID,Name 
     context.GetLocationHierarchy(locationID); 
    } 
} 

Das Endergebnis ist, würde ich so etwas wie dies wäre hoffen:

{ 
    "id": "1", 
    "parentId": "1", 
    "name": "TopLoc", 
    "children": [ 
     { 
      "id": "2", 
      "parentId": "1", 
      "name": "Loc1", 
      "children": [ 
       { 
        "id": "4", 
        "parentId": "2", 
        "name": "Loc1A", 
        "children": [ 
         {} 
        ] 
       } 
      ] 
     }, 
     { 
      "id": "3", 
      "parentId": "1", 
      "name": "Loc2", 
      "children": [ 
       {} 
      ] 
     } 
    ] 
} 

Antwort

9

Eine Möglichkeit, eine flache Tabelle in eine Hierarchie zu verwandeln, besteht darin, alle Ihre Knoten in ein Wörterbuch zu stellen. Iterieren Sie dann das Wörterbuch und suchen Sie für jeden Knoten nach dem übergeordneten Element und fügen Sie es den untergeordneten Elementen des übergeordneten Objekts hinzu. Von dort müssen Sie nur den Stamm finden und serialisieren. Hier

ist ein Beispielprogramm, um den Ansatz zu zeigen:

class Program 
{ 
    static void Main(string[] args) 
    { 
     IEnumerable<Location> locations = new List<Location> 
     { 
      new Location { Id = 1, ParentId = 1, Name = "TopLoc" }, 
      new Location { Id = 2, ParentId = 1, Name = "Loc1" }, 
      new Location { Id = 3, ParentId = 1, Name = "Loc2" }, 
      new Location { Id = 4, ParentId = 2, Name = "Loc1A" }, 
     }; 

     Dictionary<int, Location> dict = locations.ToDictionary(loc => loc.Id); 

     foreach (Location loc in dict.Values) 
     { 
      if (loc.ParentId != loc.Id) 
      { 
       Location parent = dict[loc.ParentId]; 
       parent.Children.Add(loc); 
      } 
     } 

     Location root = dict.Values.First(loc => loc.ParentId == loc.Id); 

     JsonSerializerSettings settings = new JsonSerializerSettings 
     { 
      ContractResolver = new CamelCasePropertyNamesContractResolver(), 
      Formatting = Formatting.Indented 
     }; 
     string json = JsonConvert.SerializeObject(root, settings); 

     Console.WriteLine(json); 
    } 
} 

class Location 
{ 
    public Location() 
    { 
     Children = new List<Location>(); 
    } 

    public int Id { get; set; } 
    public int ParentId { get; set; } 
    public string Name { get; set; } 
    public List<Location> Children { get; set; } 
} 

Hier ist die Ausgabe:

{ 
    "id": 1, 
    "parentId": 1, 
    "name": "TopLoc", 
    "children": [ 
    { 
     "id": 2, 
     "parentId": 1, 
     "name": "Loc1", 
     "children": [ 
     { 
      "id": 4, 
      "parentId": 2, 
      "name": "Loc1A", 
      "children": [] 
     } 
     ] 
    }, 
    { 
     "id": 3, 
     "parentId": 1, 
     "name": "Loc2", 
     "children": [] 
    } 
    ] 
} 
+0

Was ist der beste Weg zur Deserialisierung? – Rod

+1

@Rod Zum Deserialisieren müssen Sie nur tun 'Location loc = JsonConvert.DeserializeObject (JSON);' –

+0

Vielen Dank:) – Rod

3

Ich habe versucht, so etwas wie dies in Javascript.

list = [ 
    { 
    id: 1, 
    title: 'home', 
    parent: null 
    }, 
    { 
    id: 2, 
    title: 'about', 
    parent: null 
    }, 
    { 
    id: 3, 
    title: 'team', 
    parent: 2 
    }, 
    { 
    id: 4, 
    title: 'company', 
    parent: 2 
    } 
] 

function treeify(list, idAttr, parentAttr, childrenAttr) { 
    if (!idAttr) idAttr = 'id'; 
    if (!parentAttr) parentAttr = 'parent'; 
    if (!childrenAttr) childrenAttr = 'children'; 
    var treeList = []; 
    var lookup = {}; 
    list.forEach(function(obj) { 
     lookup[obj[idAttr]] = obj; 
     obj[childrenAttr] = []; 
    }); 
    list.forEach(function(obj) { 
     if (obj[parentAttr] != null) { 
      lookup[obj[parentAttr]][childrenAttr].push(obj); 
     } else { 
      treeList.push(obj); 
     } 
    }); 
    return treeList; 
}; 

console.log(JSON.stringify(treeify(list)));