2016-07-21 12 views
0

Ich habe ein Modell namens Kategorie, die eine rekursive (Eltern-Kind) Beziehung hat, wie folgt:ASP MVC 5 C# rekursive Bäume Gruppe und einrücken Ein Dropdown

public class Category: ITreeNode<Category> 
    { 
     public byte Id { get; set; } 
     public byte? ParentId { get; set; } 
     public string Name { get; set; } 

     public Category Parent { get; set; } 
     public IList<Category> Children { get; set; } 

    } 

Ich möchte ein Dropdownlist erzeugen, die heirachaly gruppiert auf der Grundlage der Eltern-Kind-Beziehungen, wo ich auch die übergeordnete Gruppe auswählen können wie folgt - im Grunde möchte ich die Kinder vom Eltern einrücken:

<select name="Category" id="Category"> 
     <option value="0">All</option> 
     <option value="1">Cars</option> 
     <option value="2">--Toyota</option> 
     <option value="3">--Nissan</option> 
     <option value="4">Fruits</option> 
     <option value="5">--Apples</option> 
     <option value="6">--Oranges</option> 
    </select> 

Meine Tabellendaten ist wie folgt:

Id | ParentId | Name 
---------------------- 
1 | null | Cars 
2 | 1  | Toyota 
3 | 1  | Nissan 
4 | null | Fruits 
5 | 4  | Apples 
6 | 4  | Oranges 

Zur Zeit habe ich die folgende LINQ-Abfrage, aber es erzeugt einfach eine normale Drop-Down-von-ID bestellt.

public IEnumerable<SelectListItem> GetCategoriesSelectList() 
    { 
     var categories = new List<SelectListItem> 
      { 
       new SelectListItem() {Value = "0", Text = "All" } 

      }.Concat(_context.Category.Select(x => new SelectListItem 
      { 
       Value = x.Id.ToString(), 
       Text = x.Name 
      }).OrderBy(x => x.Value).ToList()); 

     return categories 
    } 

Wie kann ich die LINQ-Abfrage ändern, um sie richtig gruppiert zu bekommen und eingekerbten für, wenn er eine Html.DropDownListFor gemacht hat verwenden.

habe ich versucht, meine ursprüngliche Auswahlliste zu ändern, eine Art von Baum zu erreichen, wie folgt, aber ich bin auf der EnumerateNodes Methode stecken. Das Original unten ist zum Ausdrucken einer UL-Liste, die ich von der folgenden Seite gezogen habe http://www.codeproject.com/Articles/23949/Building-Trees-from-Lists-in-NET. Wie durchlaufe ich es und gebe jedes Element zurück, wenn es ein Kind ist, dann an den Namen anfügen -- und zu meiner Auswahlliste hinzufügen?

public IEnumerable<SelectListItem> GetCategoriesSelectList() 
    { 
     IList<Category> listOfNodes = GetListOfNodes(); 
     IList<Category> topLevelCategories = TreeHelper.ConvertTOForest(listOfNodes); 

     var cats = new List<SelectListItem> 
     { 
      new SelectListItem { Value = "0", Text = "All"} 
     }; 

     foreach(var category in topLevelCategories) { 
      var catName = EnumerateNodes(category); 
      cats.Add(new SelectListItem { Value = category.Id.ToString(), Text = catName }); 
     } 
     return cats; 
    } 

    private List<Category> GetListOfNodes() 
    { 

    List<Category> sourceCategories = _context.Category.ToList(); 
    List<Category> categories = new List<Category>(); 
    foreach (Category sourceCategory in sourceCategories) 
    { 
     Category s = new Category(); 
     s.Id = sourceCategory.Id; 
     s.Name = sourceCategory.Name; 
     if (sourceCategory.ParentId != null) 
     { 
      s.Parent = new Category(); 
      s.Parent.Id = (int)sourceCategory.ParentId; 
     } 
     categories.Add(s); 
    } 
    return categories; 
    } 

private static string EnumerateNodes(Category parent) 
{ 
    if (category.Children.Count > 0) { 
     Response.Write("<ul>"); 
     foreach(Category child in category.Children) { 
      EnumerateNodes(child); 
     } 
     Response.Write("</ul>"); 
    } 
    Response.Write("</li>"); 
} 
+0

Wo stecken Sie genau fest? Wenn Sie wissen wollen, wie Dropdownlist erstellen, können Sie auf [Beste Programmierung Praxis der Verwendung von Dropdownlist in ASP.Net MVC] suchen (http://stackoverflow.com/a/37819577/296861). – Win

+0

@win Ich weiß, wie man die Listen erstellt, wie man die LINQ schreibt, um sie gruppiert und eingerückt zu bekommen. – adam78

+1

Mögliches Duplikat [Build Liste Baumtyp von Eltern-Kind-Beziehung C# rekursiv überprüft] (http://stackoverflow.com/questions/15867478/build-tree-type-list-by-recursively-checking-parent-child-relationship -c-sharp) – Win

Antwort

0

Sie können zunächst die übergeordneten Kategorien auswählen (wo ParentId ist null) und dann für jede übergeordnete Kategorie, wählen Sie die untergeordneten Kategorien.

public IEnumerable<SelectListItem> GetCategoriesSelectList() 
{ 
    var categories = _context.Category.ToList(); 
    // Initialise list and add first "All" item 
    List<SelectListItem> options = new List<SelectListItem> 
    { 
     new SelectListItem(){ Value = "0", Text = "All" } 
    }; 
    // Get the top level parents 
    var parents = categories.Where(x => x.ParentId == null); 
    foreach (var parent in parents) 
    { 
     // Add SelectListItem for the parent 
     options.Add(new SelectListItem() 
     { 
      Value = parent.Id.ToString(), 
      Text = parent.Name 
     }); 
     // Get the child items associated with the parent 
     var children = categories.Where(x => x.ParentId == parent.Id); 
     // Add SelectListItem for each child 
     foreach (var child in children) 
     { 
      options.Add(new SelectListItem() 
      { 
       Value = child.Id.ToString(), 
       Text = string.Format("--{0}",child.Name) 
      }); 
     } 
    } 
    return options; 
} 
+0

ich Fehler 'Es gibt bereits eine offene Datareader mit diesem Befehl zugeordnet ist, die in der folgenden Zeile' foreach (var Kind bei Kindern) geschlossen first.' werden müssen '. Zur Behebung habe ich 'var categories = _context.Category;' zu 'var categories = _context.Category.ToList()' verbessert. Theres auch ein Tippfehler auf der Linie 'var Kinder = products.Where (x => x.ParentId == parent.Id);' Dies sollte 'var Kinder = categories.Where sein (x => x.ParentId == Eltern. Id); 'Wenn Sie Ihre Antwort ändern, kann ich sie als Lösung markieren. Prost. – adam78

+0

Jetzt aktualisiert. :) –